-
-
Notifications
You must be signed in to change notification settings - Fork 951
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
feat(API): on exception, select most specific error handler available #1603
feat(API): on exception, select most specific error handler available #1603
Conversation
47951cb
to
a7398b7
Compare
Would this change warrant a towncrier entry? Or a |
a7398b7
to
97e297e
Compare
Codecov Report
@@ Coverage Diff @@
## master #1603 +/- ##
======================================
Coverage 100% 100%
======================================
Files 40 40
Lines 2692 2692
Branches 397 397
======================================
Hits 2692 2692 Continue to review full report at Codecov.
|
@csojinb Re Towncrier I would think, yes, we need an entry (or actually two?) since it is both a breaking change, and a new feature. |
falcon/api.py
Outdated
@@ -269,7 +269,8 @@ def __call__(self, env, start_response): # noqa: C901 | |||
# next-hop child resource. In that case, the object | |||
# being asked to dispatch to its child will raise an | |||
# HTTP exception signalling the problem, e.g. a 404. | |||
responder, params, resource, req.uri_template = self._get_responder(req) | |||
responder, params, resource, req.uri_template = self._get_responder( | |||
req) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Not a big deal, but do we need additional space for self._get_responder
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You mean, move it to another line because it's past 80 characters? Or, are you asking if this change shouldn't have occurred?
I didn't intentionally make this change here, I think it must have been my auto-pep8. It looks like Falcon's pep8-checker rules allow 99-character lines, so probably I should revert this newline change. I guess my tool didn't pick up the config.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah, falcon allows 99-characters lines, flake8 config.
In that case, I think would be better to revert that newline change
falcon/api.py
Outdated
@@ -879,7 +898,8 @@ def _get_body(self, resp, wsgi_file_wrapper=None): | |||
iterable = wsgi_file_wrapper(stream, | |||
self._STREAM_BLOCK_SIZE) | |||
else: | |||
iterable = helpers.CloseableStreamIterator(stream, self._STREAM_BLOCK_SIZE) | |||
iterable = helpers.CloseableStreamIterator( | |||
stream, self._STREAM_BLOCK_SIZE) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
And the same here:)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This looks good, do you think you can finish this up soon? I'd love to get this merged for the alpha release. AFAICT the remaining TODO items include:
- Add towncrier news fragments
- Rebase on master (fix conflicts)
- Tweak docstrings (optional)
- Tweak line wrapping (optional)
Yes, I can try to do it this weekend
…On Thu, Dec 12, 2019 at 13:44 Kurt Griffiths ***@***.***> wrote:
***@***.**** requested changes on this pull request.
This looks good, do you think you can finish this up soon? I'd love to get
this merged for the alpha release. AFAICT the remaining TODO items include:
- Add towncrier news fragments
- Rebase on master (fix conflicts)
- Tweak docstrings (optional)
- Tweak line wrapping (optional)
------------------------------
In falcon/api.py
<#1603 (comment)>:
> app.add_error_handler(falcon.HTTPError, custom_handle_http_error)
- app.add_error_handler(CustomException)
+ app.add_error_handler(Exception, custom_handle_uncaught_exception)
+ app.add_error_handler(falcon.HTTPNotFound, custom_handle_404)
+
+ If an instance of ``falcon.HTTPForbidden`` is raised, it will be
double backticks are fine, although I tend to add parens to the function
name myself to help make it obvious what it is.
Re class names, I'm fine either way TBH, since you are referencing example
code here. But it couldn't hurt to add the :class: directive.
—
You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub
<#1603?email_source=notifications&email_token=ABRVDSYBXSEUQM545YHV3I3QYKA7HA5CNFSM4JIGEACKYY3PNVWWK3TUL52HS4DFWFIHK3DMKJSXC5LFON2FEZLWNFSXPKTDN5WW2ZLOORPWSZGOCPAWL7Q#pullrequestreview-331441662>,
or unsubscribe
<https://github.com/notifications/unsubscribe-auth/ABRVDS5R4LKUAQNI3GFPSEDQYKA7HANCNFSM4JIGEACA>
.
|
`_handle_error` returns false when the exception does not match a custom handler and is not a subclass of ``HTTPError``, ``HTTPStatus``, or ``Exception``. The update to include ``Exception`` was missed in PR falconry#1527, which added a default handler for ``Exception``
Addresses falconry#1514 Rather than selecting error handlers in LIFO order of registration, select the error handler corresponding to the nearest direct ancestor of the exception type raised. So, for example, if an app only adds a custom error handler for the Python ``Exception`` class, and an ``HTTPForbidden`` error is raised, then we use the default handler for ``HTTPError`` rather than the more general ``Exception`` handler (which is the pre-existing behavior). This is implemented by storing error handlers on the API object as a dict rather than a list and looking them up using the method resolution order attribute (`__mro__`) on the raised exception class. NOTE: This commit only includes the actual implementation and does not address testing or documentation. I am seeking implementation feedback before completing those additional changes. BREAKING CHANGE: Registration of a new error handler for type E will no longer override previously-registered error handlers for subclasses of type E. Registration order will no longer matter *except* when multiple error handlers are registered for the exact same exception type, in which case the most recently registered error handler overrides the previous ones.
0c7341d
to
39d2d81
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looking great 👍
Just one thing, not sure if the GH PR interface is playing tricks on me, or did you happen to reintroduce falcon/api.py
by manual master merge? This file is now removed in master
.
Oh, so it is. I guess kdiff made that decision for me and I didn't look closely enough. I'll fix it and re-push |
For the change in error-handler-match strategy
39d2d81
to
347eed1
Compare
@vytas7 fixed |
Moving my copied TODO list out of the PR description into this comment: TODOs:
(Turns out you can't just check off checkboxes in someone else's comment.) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
👍
🎉 |
Summary of Changes
Rather than selecting error handlers in LIFO order of registration, select the error handler corresponding to the nearest direct ancestor of the exception type raised. So, for example, if an app only adds a custom error handler for the Python
Exception
class, and anHTTPForbidden
error is raised, then we use the default handler forHTTPError
rather than the more generalException
handler (which is the pre-existing behavior).This is implemented by storing error handlers on the API object as a dict rather than a list and looking them up using the method resolution order attribute (
__mro__
) on the raised exception class.NOTE:
This commit only includes the actual implementation and does not address testing or documentation. I am seeking implementation feedback before completing those additional changes.Tests and documentation have been added. Thanks @vytas7 for implementation notes!BREAKING CHANGE:
Registration of a new error handler for type
E
will no longer override previously-registered error handlers for subclasses of typeE
. Registration order will no longer matter except when multiple error handlers are registered for the exact same exception type, in which case the most recently registered error handler overrides the previous ones.Related Issues
Addresses #1514.
I believe it would also allow reversion of #1599.Not true. I misremembered why #1599 was needed.Pull Request Checklist
This is just a reminder about the most common mistakes. Please make sure that you tick all appropriate boxes. But please read our contribution guide at least once; it will save you a few review cycles!
If an item doesn't apply to your pull request, check it anyway to make it apparent that there's nothing to do.
docs/
.docs/
.versionadded
,versionchanged
, ordeprecated
directives.docs/_newsfragments/
. (Runtowncrier --draft
to ensure it renders correctly.)If you have any questions to any of the points above, just submit and ask! This checklist is here to help you, not to deter you from contributing!
PR template inspired by the attrs project.