0

So I have a Sinatra API containing this piece of code in a model:

def self.delete(account_id)
    # using Sequel, not ActiveRecord:
    if Account[account_id][:default] == true
        abort("Impossible to delete a default account. Please first set another account to default.")
    end
    # rest of the code
end

then, in app.rb :

delete '/account/:id' do
    if Account.delete(params[:id]) == 1
        status 200
    else
        status 500
    end
end

On the client side (vuejs app), I would like the error message to be displayed. Instead, when the error produces, I get a SystemExit with the error message.

How do I send that SystemExit message to the server?

thiebo
  • 1,339
  • 1
  • 17
  • 37
  • 2
    Why are you using `abort`? You should be sending back something easier to handle like `true` or `false`, especially since you can then do `if (Account.delete(...))` with no `== 1` required. – tadman Sep 30 '22 at 09:11
  • I'm using `abort` because I want to set a custom (localized) error message in the model (in order not to copy that message throughout the vuejs app. If there's a better way to achieve that... – thiebo Sep 30 '22 at 09:15
  • 2
    Where are you trying to send this message? The way ActiveRecord does this normally is via exceptions, which you can `rescue`, and it makes for a fairly straight-forward controller implementation. – tadman Sep 30 '22 at 09:25
  • 2
    Using `abort` is problematic because it's intended to bring the whole process down, and interrupting it is supposed to be a last resort, normally just for some emergency clean-up before the process is terminated. It's like setting off a nuclear bomb to send a message. – tadman Sep 30 '22 at 09:26

1 Answers1

1

In Ruby in general you want to break out of execution either by using return, exceptions or throw/catch. abort is rarely if ever used as it will immediately halt execution of the entire program - and prevent you from doing stuff like cleaning up or actually sending a meaningful response to the client besides whatever error page the web server will render if you just quit the job half way though.

You can easily implement this by creating your own exception class:

class AccountDeletionError < StandardError
end
def self.delete(account_id)
  # using Sequel, not ActiveRecord:
  if Account[account_id][:default] == true
    raise AccountDeletionError.new, "Impossible to delete a default account. Please first set another account to default."
  end
end
delete '/account/:id' do
  if Account.delete(params[:id]) == 1
    status 200
  end
  rescue AccountDeletionError => e
    status 409 # not 500. 
    content_type :json
    { error: e.message }.to_json
  end
end

Now that you know how to handle errors you should probally address the next possible one - when an account cannot be found.

max
  • 96,212
  • 14
  • 104
  • 165