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
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:
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.)
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 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.