Closed willhbr closed 2 years ago
This is a good point. I actually thought about this previously, but haven't found a good solution yet.
Catching exceptions from mruby calls should not be a problem, calling a Ruby script should already do that automatically. But the other way around is not so trivial.
Some of the general implementation ideas for Anyolite itself:
noexcept
in C++), but I'm not sure which of the two would be the better approach.I will definitely try to find a solution for the next minor release, but for now it's still a design question.
Update: I included simple safeguards to the Ruby function calling routines and tested whether they influence the performance in a significant way.
They didn't (the program even sped very slightly up for some reason), so the main
branch now has a new commit, which introduces these safeguards.
They simply pass any catchable Crystal exception to Anyolite.raise_runtime_error
as a simple message.
In the future, there could be a routine to differentiate between different exception types, but for now this should at least prevent some arithmetic overflow in a Crystal routine crashing the whole script.
I hope this helps - and please feel free to add any more suggestions to improve these routines :)
Since there don't seem to be other problems, I will close this issue now. I also added some more improvement to exception handling (the Crystal backtrace is now visible and the exception types are a bit more helpful than simple runtime errors).
For further discussions, feel free to open a thread in the 'Discussions' tab (or here, if there is a bug).
Sorry, haven't had any time to work on side projects recently and wanted to give this a proper shot with my project.
This looks like it'll do what I want, thanks! I'll let you know if there are any edge cases that I run into :)
What is the best way of having exceptions propagate correctly between Ruby and Crystal?
As far as I can see the way to do this is the
Anyolite.raise_*_error()
macros, but as far as I can tell this doesn't allow Crystal to catch errors thrown in Ruby code, or for those errors to propagate back into the Ruby code that called the Crystal method.I am currently doing some of this by checking the result of the return value from
Anyolite.call_rb_block
, checking if it is a RubyException
, and wrapping it in a custom Crystal exception with the same method and backtrace.A few of the scenarios that I would like to handle are:
Ideally, any exception raised by Crystal code would be wrapped into a custom Ruby exception, and vice versa. The simplest thing to do would be to catch any exception raised in Crystal and wrap it in a
Anyolite.raise_runtime_error
, and check the result of any Ruby block and raise that as a Crystal runtime error.Help & pointers appreciated!