What is a best practice for HtmlDialog error handling

Looking at the Ruby HtmlDialog class, I am having trouble understanding how I would perform client side error handling when there’s an error in my ruby code. For instance, I am using sketchup.callback_method_name to invoke the callback method from my html dialog. From what I can see, there’s only one callback available on sketchup.callback_method_name which is onCompleted. I assume there’s an onError but I’m just assuming as there’s no mention of this on the docs. Second, I don’t see how it would be called from the ruby side.

For instance, from the dialog.add_action_callback, I simulated an error as such:
dialog.add_action_callback(“sendEmail”) do |action_context, toEmail|
begin
raise CustomError, “Simulated error”
create_bom()
send_bom()
rescue CustomError => e
puts “Error: #{e.message}”
end
end

The error gets put but onCompleted is still called. I’d like it so that from the rescue I can do something so that onError (if it exists) gets called.

I tried returning false from the rescue statement and all of SketchUp crashed.

Cheers

Please post code correctly on the forum:


Yes, it is wrapped inside a JS Object parameter. But each Ruby callback can have it’s own object parameter with a distinct onCompleted function.

Incorrect. You should not make assumptions without evidence.

Of course, it gets called because you added in a rescue clause that trapped the Ruby exception and did not reraise it. So, execution then resumes following the beginrescueend block. And since there is nothing else to do, the callback has “completed”.

I think that the onCompleted JS callback can receive the return value from the Ruby-side callback block if you give it a parameter variable. Somewhere ThomThom showed an example of this.


Also, it may be cleaner Ruby if you define a true Ruby method to handle the callback tasks, and then the def acts as the block opener for the rescue clause.

def bom_task(toEmail)
  create_bom()
  send_bom(toEmail)
rescue => e
  puts e.inspect
  e.message
else
  'Success - BOM created'
end

def add_callbacks(dialog)
  dialog.add_action_callback('bomTask') do |action_context, toEmail|
    bom_task(toEmail)
  end
end

In the JavaScript:

function createBOM() {
  sketchup.bomTask(
    'argument',
    {
      onCompleted: function(result) {
        console.log(`The result was: ${result}`);
      }
    }
  );
}

To see the JS console you need to open the Chrome DevTools. (Right click on the dialog)

So, obviously, if the result gets returned to the JS-side, your JS onCompleted callback function can act conditionally upon the content of the result.


The docs also warn you that the reference for the dialogs should be persistent @vars otherwise the dialog object could go out of scope and get garbage collected … Poof! gone.

1 Like