Exception safety

Hey everyone,

I fell a bit in love with crystal.

The only thing that I’m left worrying about is exception safety of third-party code, including stdlib. i.e. how do I know if a method I’m calling raises? And how do I know which type of exceptions it could raise?

Even if I’d read the actual source of the method I’m calling and it doesn’t raise: what if the method calls other methods that can raise? Or worse: What if the method changes in the future and starts to raise?

How do you guys handle this? Is there any static analyser that provides guardrails like this or is there even an initiative regarding adding it to the compiler?

So many questions :grinning:

At this point the only way is by either looking at the source, or more ideally the author documents that in the API docs of the method.

Keep an eye on the changelog I guess :person_shrugging:.

It hasn’t really been a big deal for me so far. Most methods that raise also have a version that returns nil. E.g. if a hash key doesn’t exist, etc. So depending on the context I’ll properly handle the case where it doesn’t exist to avoid surprises. Otherwise if there is an unexpected exception I’d usually find it in specs, or worst case see it in logs and just fix it, with my application gracefully handling unexpected exceptions; either from an edge case, or legitimate bug that was missed.

There are some issues related to this tho:

1 Like


Thinking about creating a static analyser rule for that.

Best case scenario for me, speaking as a beginner in crystal, would be a def method raises language expression. :slight_smile:

You relax and learn to love the uncertainty…

In anything but the most simple of apps you cannot possibly handle every possibly error. How to handle an out of memory error in the SSL layer? You don’t, you accept everything will go down in flames if that happens. You have some strategically placed rescues that print a nice error message or tries to log it somewhere. The specific exceptions you might want to catch and handle are usually documented. As for the rest: there’s usually not much you can do about it than establish the fact that the code called couldn’t do what you asked it to do, and that means your code can’t either, so there’s often not much else to do than close up shop.


I agree on that.
Exceptions are exceptional. You might want to catch some kinds of exceptions at some strategic points in your program, in order to allow it to recover and move on somehow.

In some languages, exceptions are used more for purposes of directing control flow between layers of a program. Not sure if you’re coming from that angle. But this is typically avoided in Crystal because exceptions have quite a high overhead cost.