Avoid rescuing StandardError
Problems ๐
Rescuing from StandardError
causes important issues to not bubble up.
There are 300+ errors that inherit from StandardError
in Rails.
By rescuing StandardError
all these errors will be caught, meaning we donโt get good feedback in production so to whatโs wrong.
This also causes problems when writing failing tests. The code under test will fail silently. Engineers then waste time figuring out why the test failed.
Bad ๐
def perform!
Rails.error.handle(
StandardError, # Rescue a generic exception
fallback: -> { Failure.new("Something went wrong") } # Return a generic error
)
# ... perform work ...
end
end
class BigMarkerAPIClient
def all
Rails.error.handle(
StandardError, # Rescue a generic exception
fallback: -> { Failure.new("Something went wrong") } # Return a generic error
)
# ... API request ...
end
end
end
class BigMarkerAPIClient
def all
# ... API request ...
rescue StandardError
Sentry.capture_message("Something went wrong")
end
end
Good ๐
def perform!
Rails.error.handle(
TooManyRequests, # Rescue a specific exception
fallback: -> { Failure.new(TooManyRequests.new) } # Return a specific error
) do
# ... perform work ...
end
end
class Lead
def charge
# ... sometimes the lead has expired ...
rescue LeadExpired => error
Rails.error.report(error, severity: :error) # Sends the error to both Datadog and Sentry
end
end
Or let the code blow up and catch at a higher level:
class Lead
def charge! # Note the bang
# ... sometimes the lead has expired ...
end
end
Edge Cases ๐
There are a handful of cases where rescuing StandardError
is appropriate.
One example - when youโre creating a utility method such as a logger where it must not halt execution of the app.
In these cases, mark the exception as an error in Sentry so we get notified:
Rails.error.handle(StandardError, severity: :error) do