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

Add error handler class #302

Conversation

valentin-krasontovitsch
Copy link

To handle setup exceptions, a method was added to each error handler.

Said method is subsequently called when setup of the client fails.

This is to ensure that a failed setup is not only logged, but also
reported to e.g. sentry.

Furthermore, a base class indicating the interface for error handlers is added.

Closes #288

Valentin Krasontovitsch added 2 commits December 5, 2017 15:36
To handle setup exceptions, a method was added to each error handler.

Said method is subsequently called when setup of the client fails.

This is to ensure that a failed setup is not only logged, but also
reported to e.g. sentry.

Closes ruby-amqp#288
include Logging

def handle(properties, payload, consumer, ex)
raise NotImplementedError.new
Copy link
Contributor

@sldblog sldblog Dec 5, 2017

Choose a reason for hiding this comment

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

Unfortunately, NotImplementedError is subclassed from ScriptError which is subclassed from Exception.

I think it would be safer to use something that can be caught by StandardError. I'm assuming that most top-level error handlers do a generic rescue, which would only catch StandardError subclasses.

Choose a reason for hiding this comment

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

There seems to be no standard way of doing this besides the above, and not throwing an Error, but relying on the no method error being thrown when a subclass doesn't implement the method.

Do you suggest to define a custom Error class that inherits from StandardError?

Please cf. #297 for links to discussions regarding the above error... I'm a newbie to ruby (heh, that rhymed), so I really don't feel confident to make a call, due to the different opinions I found...

Also, we should probably fix the ack base class as well if we mind the above.

Copy link
Member

Choose a reason for hiding this comment

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

NotImplementedError is right on the money in terms of what we'd like to communicate, though.

Choose a reason for hiding this comment

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

Again, I don't really know, not a seasoned ruby programmer, but: the docs for the NotImplementedError can be interpreted in such a way that it is only to be used for instanced where a feature is not implemented on the current platform, due to a hardware / software deficit of the underlying system, not a missing implementation in the ruby code.
Even the error message in error.c, where the error class is defined, sounds as follow:
[$FUNCTION_NAME() function is unimplemented on this machine](https://github.com/ruby/ruby/blob/1ae69a20645d7be556fd0ecd001b0bb5f3959330/error.c#L2338)

Of course I don't actually get that message when I raise the error in irb, just get the text NotImplementedError...

The above are just meant as hints - you guys should decide how to handle this problem : )

Copy link
Contributor

@sldblog sldblog Dec 6, 2017

Choose a reason for hiding this comment

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

I don't think this discussion has to delay this PR, it's great :)

I have only called this out because in April this year we had apps not working due to a missed implementation, and we did not get any Honeybadger reports since it was a NotImplementedError and zipped past through all layers of error reporting.

Copy link
Member

@michaelklishin michaelklishin Dec 6, 2017

Choose a reason for hiding this comment

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

@sldblog the fact that in Ruby a rescue without specific exceptions doesn't catch everything (match all Exception subclasses) not a problem library authors should worry about. Ruby designers made a mistake, using a rescue without an exception class is therefore is not a good idea. NotImplementedError is exactly the exception that should be used in this case.

@@ -90,6 +90,9 @@ def start_work_loop
@worker.run
:success
rescue ConnectionError, AuthenticationError, WorkerSetupError => ex
Hutch::Config[:error_handlers].each do |backend|
backend.handle_setup_exception(ex)
end
Copy link
Contributor

Choose a reason for hiding this comment

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

One thing though, could this be tested in cli_spec, please?

Copy link
Member

@michaelklishin michaelklishin 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 a test case, as requested in the comments.

@valentin-krasontovitsch
Copy link
Author

valentin-krasontovitsch commented Dec 6, 2017 via email

@michaelklishin
Copy link
Member

@valentin-krasontovitsch thank you.

@valentin-krasontovitsch
Copy link
Author

So I just pushed a commit that introduces a test case, making sure that if Hutch.connect throws an error, that error is passed to all backends.

I'm not super happy with the test, as it relies on the implementation of the tested method: start_work_loop is tested, and we assume that the method calls Hutch.connect, which in turn is used to raise an exception.

If you have any pointers or ideas about how this could be tested in a less brittle way, let me know.

Maybe the coupling to the implementation is OK in this case...

@valentin-krasontovitsch
Copy link
Author

So I'm basically happy with the other merge request merged in, but just for completeness sake: Any new thought / comments on the test I wrote?

@michaelklishin
Copy link
Member

@valentin-krasontovitsch sorry, this slipped through the cracks. What's the other PR you are referring to? Is this one still relevant and would you like us to review it?

@michaelklishin michaelklishin merged commit e15d8df into ruby-amqp:master Jan 10, 2018
@valentin-krasontovitsch valentin-krasontovitsch deleted the 288_add_error_handler_class branch January 10, 2018 16:12
@valentin-krasontovitsch
Copy link
Author

no worries : )
the other PR was #301, included the first two commits of this merge request, and got merged immediately - while here (rightfully) the lacking unit tets was pointed out (and mitigated).

I guess as you've merged this one now, i don't need to answer your second question anymore ^^

michaelklishin added a commit that referenced this pull request Jan 17, 2018
 * amq-protocol is not used on JRuby
 * All connections must be closed on JRuby since Hutch/MarchHare
   do not instruct RabbitMQ Java client to use daemon threads.
   Not doing so will result in hanging test suites since the JVM
   won't terminate with live non-daemon threads.

References #302, #305.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants