Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Update exception handling in tools #2594

Merged
merged 9 commits into from
Jul 31, 2024
Merged

Update exception handling in tools #2594

merged 9 commits into from
Jul 31, 2024

Conversation

mexanick
Copy link
Contributor

@mexanick mexanick commented Jul 17, 2024

Following some real-world experience with my own changes proposed before, I believe this would be a better way to handle custom runtime exceptions with the custom exit codes.

  • Remove SystemExit handling in Tool.run()
    • decided to keep
  • Add a possibility to register custom exceptions and handle them in Tool.run() with the preservation of the exit code.

@mexanick mexanick requested review from Tobychev and maxnoe July 17, 2024 13:28
@mexanick mexanick self-assigned this Jul 17, 2024
@@ -443,6 +449,19 @@ def run(self, argv=None, raises=False):
Provenance().finish_activity(
activity_name=self.name, status="interrupted", exit_code=exit_status
)
except self.custom_exceptions as err:
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we should still catch the SystemExit with error code != 0 case here, I think this was the cause of the issue for #1881

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ok, SystemExit treatment is added back

This comment has been minimized.

src/ctapipe/core/tool.py Outdated Show resolved Hide resolved
@maxnoe
Copy link
Member

maxnoe commented Jul 17, 2024

btw.: I simplified the SystemExit part here:
https://github.com/cta-observatory/ctapipe/pull/2591/files#diff-73435d23e062b16d391308f70039eb8d6bc9c40c1b12d03e9737eb4ec91b36f3R456
after realizing that raise SystemExit is no different than sys.exit(), so raise doesn't make sense for it

This comment has been minimized.

1 similar comment

This comment has been minimized.

@mexanick mexanick requested a review from maxnoe July 18, 2024 06:49
@maxnoe
Copy link
Member

maxnoe commented Jul 18, 2024

How about introducing a member variable exit_code on the Tool, so that the need for custom exceptions is not there, but tools can just do:

self.exit_code = 5
raise ValueError(...)

However, I don't really see why this is different to just doing this in the tool:

log.critical("Error condition foo")
self.exit(5)

@mexanick
Copy link
Contributor Author

The exceptions can be raised in the components that tool uses, in this case what you propose is still possible, but requires additional boiler plate try-except code in every tool. Here, for the price of a bit more complex exception handling, we can properly catch all the exceptions raised in the Tool itself or in the components it uses, and also keep the definition of exit codes tightly coupled to exceptions themselves. Adding an exit_code attribute to the tool seems to be redundant to me.

@maxnoe
Copy link
Member

maxnoe commented Jul 18, 2024

That means a component down the line would already specify the exit code?

What if a component is used in more than one tool?

@maxnoe
Copy link
Member

maxnoe commented Jul 18, 2024

I think it would be much more straight forward to catch the exception where it appears in your tool:

try:
    self.comp.foo()
except Exception:
     self.exception("comp failed doing foo")   
     self.exit(5)

@mexanick
Copy link
Contributor Author

mexanick commented Jul 18, 2024

That means a component down the line would already specify the exit code?

I'm in favor of defining custom exceptions specifying the exit code, i.e. one exception can be reused between the components or tools if needed and the exit code is tied to this particular exception.

What if a component is used in more than one tool?

I don't see a problem here... can you elaborate?

I think it would be much more straight forward to catch the exception where it appears in your tool:

try:
    self.comp.foo()
except Exception:
     self.exception("comp failed doing foo")   
     self.exit(5)

This is an option, but as I wrote above, would require more boiler plate code above. Since I'm still in favor of having exit code being tied to the custom exception, this should become like this:

try:
    self.comp.foo()
except MyCustomException as exc:
    self.log.exception(".{}", exc)
    self.exit(exc.exit_code)

which is basically the same that's added to the Tool's exception handling in the PR.

@mexanick
Copy link
Contributor Author

CI failed because of broken provenance, will rebase as soon as #2595 is merged

- Remove SystemExit handling in `Tool.run()`
- Add a possibility to register custom exceptions
  and handle them in `Tool.run()` with the preservation of the exit code.
- Simplify SystemExit handling
- Remove custom exception registration,
  but add a treatment of the custom exit codes when catching generic Exception

This comment has been minimized.

src/ctapipe/core/tool.py Outdated Show resolved Hide resolved

This comment has been minimized.

@mexanick mexanick requested a review from maxnoe July 22, 2024 08:37
@mexanick
Copy link
Contributor Author

@maxnoe @Tobychev can you please take a look?

Tobychev
Tobychev previously approved these changes Jul 29, 2024
Copy link
Member

@maxnoe maxnoe left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please add some documentation on this to the docstring of Tool.

Copy link

Passed

Analysis Details

0 Issues

  • Bug 0 Bugs
  • Vulnerability 0 Vulnerabilities
  • Code Smell 0 Code Smells

Coverage and Duplications

  • Coverage 100.00% Coverage (93.60% Estimated after merge)
  • Duplications 0.00% Duplicated Code (0.60% Estimated after merge)

Project ID: cta-observatory_ctapipe_AY52EYhuvuGcMFidNyUs

View in SonarQube

@maxnoe maxnoe requested a review from kosack July 31, 2024 12:13
@kosack kosack merged commit 8117dcd into main Jul 31, 2024
13 checks passed
@kosack kosack deleted the update-exception-handling branch July 31, 2024 14:41
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants