Open operations

I suppose a good developer would wrap all his code in begin rescue. I don’t, and the result has always been errors show up in the console and the method stops execution at the point where the error occurred.

I did notice recently though that if an error occurs in an operation the operation is left open. The result is that my UI::HtmlDialog no longer responds to dialog.execute_script(script).

As a work around I created my own wrapper that automatically aborts the operation when an error occurs. It seems to work fine, but I thought I would ask for opinions before I do a mass replacement.

  def do_operation(op_name, disable_ui = false, next_transparent = false, transparent = false, &block)
    Sketchup.active_model.start_operation(op_name, disable_ui, next_transparent, transparent)
    begin
      block.call if block_given?
    rescue StandardError => e
      Sketchup.active_model.abort_operation
      raise e
    end
    Sketchup.active_model.commit_operation
  end

def do_something
  do_operation('Error Prone Task', true) do
    #do error prone tasks here.
  end
end

def do_something_else(operation = false)
  pr = proc do
    #error prone code here
  end
  if operation
    do_operation('Task', true) { pr.call }
  else
    pr.call
  end
end

This is another edition …

  def do_operation(op_name, disable_ui = false,
    next_transparent = false, transparent = false
  )
    return nil unless block_given?
    model = Sketchup.active_model
    begin
      model.start_operation(op_name, disable_ui, next_transparent, transparent)
      result = yield
    rescue => e
      model.abort_operation
      raise e
    else
      model.commit_operation
      return result
    end
  end

We’ve discussed some of this before …

The 2016 release Observer Updates primer mentions this:

… and we have a couple of tracker issue threads open:

1 Like

Hm… that sounds unexpected. Do you have a sample script for this?

Before about aborting operations if you are doing transparent operations. It will undo the operation you are trying to chain to - not only the one you tried to append.

(And if you make yourself a wrapper for model.start_operation - don’t expose next_transparent as that argument is something you really shouldn’t use. It’s still left working in the API because it’s the only workaround for a couple of other bugs. Otherwise we’d made that a noop by now.)

I’ll try to put together a sample.

No fix for that? Perhaps if it’s transparent, then I should commit the operation instead of aborting?

Thanks for that advice.

Yes, that is probably the safest (though, it might not be easy to clean up what your operation might already have done.)

Now that I think of it… I wonder if we can in fact allow this. If we introduced a new optional argument to model.abort_operation to not chain the abort.

I logged an issue to look into that: Abort last transparent operation · Issue #622 · SketchUp/api-issue-tracker (github.com)

2 Likes

I was trying to make up a sample script for this and determined that the problem isn’t where I thought it was. It seems like the Sketchup::SelectionObserver is the culprit. Apparently selection change events are queued up until after the transaction commits or aborts. I will do further testing to see if the disable_ui flag has any effect on that.

1 Like

Here is the issue with reproduction steps and code.

1 Like