I'm looking for the best way to catch and handle exceptions in a rails app from service classes.
I have a class which calls service x, service x returns an error if the user info is wrong. At the moment we handle the error and delete previously created objects in the DB.
class Main
...
error_response = ServiceX.new(hash).run
if error_response
StampRequest.delete(stamp_requests)
raise StampError, error_response[:error]
end
...
end
The problem is that service x calls several other services, including external an external AWS and currently if these services fail or cause an exception I'm not sure of the best way or 'rails way' to handle these errors and pass them back to the main class. Currently, if for example the call to the AWS service fails, the main class has no way of knowing this.
class ServiceX
...
return error_response unless subscribed_to_price_alert_users_available?(subscribed_to_price_alert_users)
subscribed_to_price_alert_users.each do |user|
PricingMailer.notify(user, user_hash(user)).deliver_later
Sms::PricingSms.new(build_hash(user)).submit
PricingService.new(user, reminder_hash(user)).submit unless reminders?
end
# return nil to indicate success
nil
end
...
end
If the external services fail I want to then delete the StampRequests
from the DB as I do if there is a user error.
Passing nil
for success is not the best/right way. Hope the below code snippet may help you.
class Main
...
begin
ServiceX.new(hash).run
rescue StandardError, AWSError => exception
...
StampRequest.delete(stamp_requests)
raise StampError, exception.message
end
end
class ServiceX
...
raise StandardError.new(error_response) unless subscribed_to_price_alert_users_available?(subscribed_to_price_alert_users)
# Assuming you have AWS/External service calls in this loop
# Let it raise exception (AWSError), this has to be handled wisely by the caller of this function.
# In this case caller: a fn in Main class, it has rescue block to handle this exception
subscribed_to_price_alert_users.each do |user|
PricingMailer.notify(user, user_hash(user)).deliver_later
Sms::PricingSms.new(build_hash(user)).submit
PricingService.new(user, reminder_hash(user)).submit unless reminders?
end
...
end
Collected from the Internet
Please contact [email protected] to delete if infringement.
Comments