Skip to content

feat: Log and Handle Error for Event Dispatcher response #221

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

Merged
merged 3 commits into from
Dec 5, 2019

Conversation

oakbani
Copy link
Contributor

@oakbani oakbani commented Dec 3, 2019

Summary

  • Allows Event Dispatcher to receive an optional logger and error handler
  • Logs and calls Error Handler for Timeout or any other error raised.
  • Logs and calls Error Handler if response results into 4xx or 5xx status code.

Test plan

  • Added new unit tests.

Issues

  • OASIS-5687

@coveralls
Copy link

coveralls commented Dec 3, 2019

Coverage Status

Coverage increased (+0.005%) to 99.514% when pulling 2dc51ec on oakbani/revise-event-dispatcher into c720b02 on master.

@coveralls
Copy link

Coverage Status

Coverage increased (+0.02%) to 99.526% when pulling 082087d on oakbani/revise-event-dispatcher into 6e84924 on master.

@oakbani oakbani requested a review from mjc1283 December 3, 2019 14:23
end

error_msg = "Event failed to dispatch with response code: #{response.code}"
Copy link
Contributor

Choose a reason for hiding this comment

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

Shouldn't it be in constants file?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

We don't follow this as a practice in the SDK. And I would prefer to keep this here as I don't expect it to be reused.

Copy link
Contributor

@mikeproeng37 mikeproeng37 left a comment

Choose a reason for hiding this comment

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

Lgtm

Copy link
Contributor

@thomaszurkan-optimizely thomaszurkan-optimizely left a comment

Choose a reason for hiding this comment

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

LGTM. I would love some sort of queue and retry mechanism.

@thomaszurkan-optimizely thomaszurkan-optimizely merged commit 3e64576 into master Dec 5, 2019
case response.code
when 400...500
@logger.log(Logger::ERROR, error_msg)
@error_handler.handle_error(HTTPCallError.new("HTTP Client Error: #{response.code}"))
Copy link
Contributor

@jasonkarns jasonkarns Dec 5, 2019

Choose a reason for hiding this comment

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

As a consumer, i would be super frustrated that I have to parse the error message to determine the actual http response code... I would request that the code be added as a property of the error type.

Relatedly, I would recommend having two separate error types for server/client. With a single error type, error handlers will need to parse the message instead of using instance matching.

Indeed, these error types don't need to be created yourself. Ruby already provides them in the standard library: https://ruby-doc.org/stdlib-2.6.5/libdoc/net/http/rdoc/Net/HTTPExceptions.html

And as a stylistic point, I'll just note that instead of handling the error here, all this code could be a single rescue => e. the 400/500 responses could be raised, and the timeout/standard error rescues be combined to a single one that logs the error message and invokes the handler. I think that would simplify all this quite a bit.

@@ -28,26 +30,46 @@ class EventDispatcher
# @api constants
REQUEST_TIMEOUT = 10

def initialize(logger: nil, error_handler: nil)
@logger = logger || NoOpLogger.new
@error_handler = error_handler || NoOpErrorHandler.new
Copy link
Contributor

Choose a reason for hiding this comment

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

I'm confused why the keyword params are defaulted to nil, only to have that default overridden?

I think the idiomatic way to do this would be:

def initialize(logger: NoOpLogger.new, error_handler: NoOpErrorHandler.new)
  @logger = logger
  @error_handler = error_handler
end

batch_size: DEFAULT_BATCH_SIZE,
flush_interval: DEFAULT_BATCH_INTERVAL,
logger: NoOpLogger.new,
notification_center: nil
)
@event_queue = event_queue
@logger = logger
@event_dispatcher = event_dispatcher
@event_dispatcher = event_dispatcher || EventDispatcher.new(logger: @logger)
Copy link
Contributor

@jasonkarns jasonkarns Dec 5, 2019

Choose a reason for hiding this comment

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

keyword args can be used within the method signature directly, there's no need to do all the manual defaulting within the body.

e.g.

def initialize(
  logger: NoOpLogger.new,
  event_dispatcher: EventDispatcher.new(logger: logger)
)

@oakbani oakbani deleted the oakbani/revise-event-dispatcher branch August 19, 2020 13:35
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.

6 participants