-
Notifications
You must be signed in to change notification settings - Fork 28
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
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,7 +1,7 @@ | ||
# frozen_string_literal: true | ||
|
||
# | ||
# Copyright 2016-2017, Optimizely and contributors | ||
# Copyright 2016-2017, 2019, Optimizely and contributors | ||
# | ||
# Licensed under the Apache License, Version 2.0 (the "License"); | ||
# you may not use this file except in compliance with the License. | ||
|
@@ -15,6 +15,8 @@ | |
# See the License for the specific language governing permissions and | ||
# limitations under the License. | ||
# | ||
require_relative 'exceptions' | ||
|
||
require 'httparty' | ||
|
||
module Optimizely | ||
|
@@ -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 | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe 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:
|
||
end | ||
|
||
# Dispatch the event being represented by the Event object. | ||
# | ||
# @param event - Event object | ||
def dispatch_event(event) | ||
if event.http_verb == :get | ||
begin | ||
HTTParty.get(event.url, headers: event.headers, query: event.params, timeout: REQUEST_TIMEOUT) | ||
rescue Timeout::Error => e | ||
return e | ||
end | ||
response = HTTParty.get(event.url, headers: event.headers, query: event.params, timeout: REQUEST_TIMEOUT) | ||
|
||
elsif event.http_verb == :post | ||
begin | ||
HTTParty.post(event.url, | ||
body: event.params.to_json, | ||
headers: event.headers, | ||
timeout: REQUEST_TIMEOUT) | ||
rescue Timeout::Error => e | ||
return e | ||
end | ||
response = HTTParty.post(event.url, | ||
body: event.params.to_json, | ||
headers: event.headers, | ||
timeout: REQUEST_TIMEOUT) | ||
end | ||
|
||
error_msg = "Event failed to dispatch with response code: #{response.code}" | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Shouldn't it be in constants file? There was a problem hiding this comment. Choose a reason for hiding this commentThe 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. |
||
|
||
case response.code | ||
when 400...500 | ||
@logger.log(Logger::ERROR, error_msg) | ||
@error_handler.handle_error(HTTPCallError.new("HTTP Client Error: #{response.code}")) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe 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 |
||
|
||
when 500...600 | ||
@logger.log(Logger::ERROR, error_msg) | ||
@error_handler.handle_error(HTTPCallError.new("HTTP Server Error: #{response.code}")) | ||
end | ||
rescue Timeout::Error => e | ||
@logger.log(Logger::ERROR, "Request Timed out. Error: #{e}") | ||
@error_handler.handle_error(e) | ||
|
||
# Returning Timeout error to retain existing behavior. | ||
e | ||
rescue StandardError => e | ||
@logger.log(Logger::ERROR, "Event failed to dispatch. Error: #{e}") | ||
@error_handler.handle_error(e) | ||
nil | ||
end | ||
end | ||
end |
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.
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.