Skip to content

Commit 145388a

Browse files
author
Stephen Hoover
authored
BUG Only set exceptions on ModelFuture if there was an error (#86)
In #79, the entire `if` gate in `ModelPipeline._set_model_exception` was removed, when I should only have removed the part after the `and`. If we don't have the `if an exception happened in the job` check, we'll set an exception on all `ModelFuture` objects, even if everything succeeded.
1 parent 48d0686 commit 145388a

File tree

3 files changed

+26
-10
lines changed

3 files changed

+26
-10
lines changed

CHANGELOG.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,8 @@ This project adheres to [Semantic Versioning](http://semver.org/).
55
## [Unreleased]
66

77
### Fixed
8+
- Fixed a bug which caused an exception to be set on all ``ModelFuture`` objects, regardless of job status (#86).
9+
- Fixed a bug which made the ``ModelPipeline`` unable to generate prediction jobs for models trained with v0.5 templates (#84).
810
- Handle the case when inputs to ``ModelFuture`` are ``numpy.int64`` (or other non-``integer`` ints) (#85).
911

1012
## 1.5.0 - 2017-05-11

civis/ml/_model.py

Lines changed: 11 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -316,7 +316,7 @@ def _set_model_exception(fut):
316316
If it indicates an exception, replace the generic
317317
``CivisJobFailure`` by a more informative ``ModelError``.
318318
"""
319-
# Prevent inifinite recursion: this function calls `set_exception`,
319+
# Prevent infinite recursion: this function calls `set_exception`,
320320
# which triggers callbacks (i.e. re-calls this function).
321321
if fut._exception_handled:
322322
return
@@ -328,15 +328,16 @@ def _set_model_exception(fut):
328328
if fut.is_training and meta['run']['status'] == 'succeeded':
329329
# if training job and job succeeded, check validation job
330330
meta = fut.validation_metadata
331-
try:
332-
# This will fail if the user doesn't have joblib installed
333-
est = fut.estimator
334-
except Exception: # NOQA
335-
est = None
336-
fut.set_exception(
337-
ModelError('Model run failed with stack trace:\n'
338-
'{}'.format(meta['run']['stack_trace']),
339-
est, meta))
331+
if meta['run']['status'] == 'exception':
332+
try:
333+
# This will fail if the user doesn't have joblib installed
334+
est = fut.estimator
335+
except Exception: # NOQA
336+
est = None
337+
fut.set_exception(
338+
ModelError('Model run failed with stack trace:\n'
339+
'{}'.format(meta['run']['stack_trace']),
340+
est, meta))
340341
except (FileNotFoundError, CivisJobFailure) as exc:
341342
# If there's no metadata file
342343
# (we get FileNotFound or CivisJobFailure),

civis/ml/tests/test_model.py

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -287,6 +287,19 @@ def test_set_model_exception_unknown_error():
287287
assert str(err.value).startswith(err_msg)
288288

289289

290+
@mock.patch.object(_model.cio, "file_to_json", autospec=True,
291+
return_value={'run': {'status': 'succeeded',
292+
'stack_trace': None}})
293+
def test_set_model_exception_no_exception(mock_f2j):
294+
# If nothing went wrong, we shouldn't set an exception
295+
ro = [{'name': 'model_info.json', 'object_id': 137, 'object_type': 'File'},
296+
{'name': 'metrics.json', 'object_id': 139, 'object_type': 'File'}]
297+
ro = [Response(o) for o in ro]
298+
mock_client = setup_client_mock(1, 2, state='succeeded', run_outputs=ro)
299+
fut = _model.ModelFuture(1, 2, client=mock_client)
300+
assert fut.exception() is None
301+
302+
290303
class ModelFutureStub:
291304

292305
def __init__(self, exc, trn, val):

0 commit comments

Comments
 (0)