Tsonnet #7 - No more YOLO exceptions
Replacing wild exception throws with monadic error-handling
Welcome to the Tsonnet series!
If you're just joining us, you can check out how it all started here.
In the previous post, we covered simple string concatenation:
Today, we'll improve our codebase by replacing ad-hoc exceptions with monadic error handling. If you're not familiar with this concept, I recommend reading my introduction to monadic error handling before continuing:
Adding monadic error-handling to Tsonnet
Let's start from the bottom up by replacing exceptions in the Json
module with Result values. The Result
type in OCaml provides a way to handle errors explicitly in our type system, making error cases visible and impossible to ignore:
The key changes here involve:
Changing the return type to `(Yojson.t, string) result`, where the first type parameter represents success values and the second represents error messages
Using
ok
anderror
constructors to wrap our return valuesCarefully handling recursive cases in
Array
andObject
types, where we need to process lists of results
Following this change, the interpreter needs to be updated. Here we mostly use the ok
function to wrap the values, but we can also get rid of one failwith
raising an exception for the invalid binary operation case:
Note the let*
definition as an alias for Result.bind
. This syntactic sugar makes our code much cleaner when working with Result
values. Instead of deeply nested match
expressions, we can write sequential-looking code that maintains proper error handling — if any step in the chain produces an error, execution stops and returns that error.
Lastly, main.ml
is required to match the result type accordingly:
Conclusion
With these changes, our error handling is now:
Type-safe: The compiler ensures we handle all error cases
Explicit: Error paths are visible in our function signatures
Composable: We can easily chain operations while maintaining proper error handling
In the next posts, we'll build upon this foundation to add more complex language features while maintaining our robust error-handling approach.