Skip to content

Commit bfab212

Browse files
committed
fix(sdk): Add error handling. Fixes #11164
Signed-off-by: Yael <fishel.yael@gmail.com>
1 parent 13f83cf commit bfab212

File tree

3 files changed

+39
-1
lines changed

3 files changed

+39
-1
lines changed

sdk/RELEASE.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
## Deprecations
99

1010
## Bug fixes and other changes
11+
* Add error handling for image build/push failures in KFP SDK. [\#11164](https://github.com/kubeflow/pipelines/pull/11356)
1112

1213
## Documentation updates
1314

sdk/python/kfp/cli/component.py

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,10 @@
6464
_COMPONENT_ROOT_DIR = pathlib.Path('/usr/local/src/kfp/components')
6565

6666

67+
class ComponentBuildError(Exception):
68+
pass
69+
70+
6771
@contextlib.contextmanager
6872
def _registered_modules():
6973
registered_modules = {}
@@ -313,8 +317,12 @@ def build_image(self, platform: str, push_image: bool):
313317
)
314318
for log in logs:
315319
message = log.get('stream', '').rstrip('\n')
320+
error = log.get('error', '').rstrip('\n')
316321
if message:
317322
logging.info(f'{docker_log_prefix}: {message}')
323+
if error:
324+
raise ComponentBuildError(
325+
f'{docker_log_prefix} ERROR: {error}')
318326

319327
except docker.errors.BuildError as e:
320328
for log in e.build_log:
@@ -339,7 +347,8 @@ def build_image(self, platform: str, push_image: bool):
339347
if status:
340348
logging.info(f'{docker_log_prefix}: {layer} {status}')
341349
if error:
342-
logging.error(f'{docker_log_prefix} ERROR: {error}')
350+
raise ComponentBuildError(
351+
f'{docker_log_prefix} ERROR: {error}')
343352
except docker.errors.BuildError as e:
344353
logging.error(f'{docker_log_prefix}: {e}')
345354
raise e

sdk/python/kfp/cli/component_test.py

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -449,6 +449,34 @@ def test_docker_client_is_called_to_build_but_skips_pushing(self):
449449
self._docker_client.api.build.assert_called_once()
450450
self._docker_client.images.push.assert_not_called()
451451

452+
def test_docker_client_failed_to_build_img(self):
453+
self._docker_client.api.build.return_value = [{'error': 'Error log'}]
454+
created_component = _make_component(
455+
func_name='train', target_image='custom-image')
456+
_write_components('components.py', created_component)
457+
458+
result = self.runner.invoke(
459+
self.cli,
460+
['build', str(self._working_dir), '--push-image'],
461+
)
462+
463+
self.assertEqual(result.exit_code, 1)
464+
self._docker_client.api.build.assert_called_once()
465+
self._docker_client.images.push.assert_not_called()
466+
467+
def test_docker_client_failed_to_push_img(self):
468+
self._docker_client.images.push.return_value = [{'error': 'Error log'}]
469+
created_component = _make_component(
470+
func_name='train', target_image='custom-image')
471+
_write_components('components.py', created_component)
472+
473+
result = self.runner.invoke(
474+
self.cli,
475+
['build', str(self._working_dir), '--push-image'],
476+
)
477+
self.assertEqual(result.exit_code, 1)
478+
self._docker_client.images.push.assert_called_once()
479+
452480
@mock.patch('kfp.__version__', '1.2.3')
453481
def test_docker_file_is_created_correctly(self):
454482
component = _make_component(

0 commit comments

Comments
 (0)