This is part of the Semicolon&Sons Code Diary - consisting of lessons learned on the job. You're in the exceptions category.
Last Updated: 2024-11-23
I had failing tests for a bulk email operation, but nothing seemed to appear in the logs and no exceptions were thrown. After much searching, I found this lump of code:
class UpsellBulkOperation
def each
collection.each do |user|
yield user
end
successful << user.email
# Here be dragons:
rescue StandardError
unsuccessful << user.email
end
{ successful: successful, unsuccessful: unsuccessful }
end
end
The issue was that the exceptions were swallowed. There was a somewhat good intention here, in that we didn't want the bulk email operation to fail to send emails to other customers. But this resilience made it difficult to debug. Some logging would have helped:
class UpsellBulkOperation
def each
collection.each do |user|
yield user
end
successful << user.email
rescue StandardError => error
Rails.logger.error("ERROR: Could not send email to #{user.email}:\n #{error}")
unsuccessful << user.email
end
{ successful: successful, unsuccessful: unsuccessful }
end
end
I discovered that I was inadvertently hiding exceptions in a production environment, with the result that I didn't receive exception notifications about certain actual errors.
In my web server, this happened with high-level wrapping exception handlers:
rescue_from StandardError do |error|
# !!! All info about exception lost for the developers
render 'errors/server_error', status: 500
end
I repaired this by intercepting with a call to Rollbar:
rescue_from StandardError do |error|
Rollbar.error(error) # fixed
render 'errors/server_error', status: 500
end
In my Javsacript client, this mistake manifested within error handlers:
{
onError: function (err) {
// All info about exception lost for the developers
showErrorMessage(
`PayaPal return an error code during payment. Please try again or contact our customer support`
)
}
}
The fix was to intercept and send the error to Rollbar first:
{
onError: function (err) {
Rollbar.error("Error with PayPal payment", err)
showErrorMessage(
`PayaPal return an error code during payment. Please try again or contact our customer support`
)
}
}