-
Notifications
You must be signed in to change notification settings - Fork 23
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
Add custom error handling #847
Add custom error handling #847
Conversation
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.
I like this design!
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 great!
lib/Zonemaster/Backend/DB.pm
Outdated
@@ -51,22 +51,25 @@ sub get_db_class { | |||
sub user_exists { | |||
my ( $self, $user ) = @_; | |||
|
|||
die "username not provided to the method user_exists\n" unless ( $user ); | |||
die Zonemaster::Backend::Error::Internal->new( reason => "username not provided to the method user_exists") | |||
unless ( $user ); |
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.
Could add an indentation here before the unless
to make it easier to read?
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.
Done
lib/Zonemaster/Backend/RPCAPI.pm
Outdated
} | ||
} | ||
|
||
sub handle_exception { | ||
my ( $method, $exception, $exception_id ) = @_; | ||
my ( $_method, $exception ) = @_; |
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.
Maybe you can remove the $_method
since it is not used, my understanding is that _build_method()
retrieve the method's name automatically.
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.
Done
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 really nice. I have one question/suggestion and a couple of formatting nits.
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.
Really nice work!
lib/Zonemaster/Backend/RPCAPI.pm
Outdated
@@ -43,7 +44,7 @@ sub new { | |||
bless( $self, $type ); | |||
|
|||
if ( ! $params || ! $params->{config} ) { | |||
handle_exception('new', "Missing 'config' parameter", '001'); | |||
handle_exception('new', "Missing 'config' parameter"); |
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.
Since the method name is not used anymore, is it still required to pass it to handle_exception()
?
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.
No, it can be removed
63d7148
to
1c803df
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.
$ make distcheck
"/usr/local/bin/perl" "-Iinc" "-MExtUtils::Manifest=fullcheck" -e fullcheck
Not in MANIFEST: lib/Zonemaster/Backend/Errors.pm
When MANIFEST is fixed, I will test. |
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.
Looks fine.
I've tested this for v2021.2 and it LGTM. The last test case listed under How to test this PR didn't work out of the box because it relies on a bug that has been fixed. Instead I injected a bug into Zonemaster::Backend::DB::PostgreSQL::test_progress() that ensures that the decoded JSON blob is invalid before attempting to parse it. After this I was able to successfully run that test case too. |
Purpose
Make error management a bit more manageable.
Context
Changes
Built on top of #843, planned to be integrated with #844 to provide server error counters.
Adds a base error type
Zonemaster::Backend::Error
extended to the following classes:Zonemaster::Backend::Error::Internal
(covers code -32603, but subclassed to add more meaning when applicable)Zonemaster::Backend::Error::JsonError
Zonemaster::Backend::Error::ResourceNotFound
(custom code -32000)Zonemaster::Backend::Error::PermissionDenied
(custom code -32001)Zonemaster::Backend::Error::Conflict
(custom code -32002)This type is used to differentiate actual unexpected server error and "normal" exceptions (a test that does not exist in the database should not result in a server error, even less in a json parsing error). Also I noticed that sometimes
null
is returned when a test is not found (like withget_test_progress
) and sometimes an error is returned, what should be the correct behavior? Returning a custom error seems to be an accepted pattern from what I have seen in other implementations, it can also have some context about the error.It also adds the possibility to add meaning and context to the error, both to the operator, in the logs, and to the user, in the response.
It theoretically adds the ability to set a custom error code but that is not yet usable due to a limitation of the JSON::RPC module. I have made a pull request to address that matter but the maintainer of the repo do not seem active anymore (the package on cpan has been marked for adoption).
If / when custom code are available in the JSON RPC module, the parameter validation should be moved after the method routing, relying on the external module to parse and validate the method (what it is already doing).
How to test this PR
Generated logs: