I am implementing a set of Motoko libraries from the bitcoin standard. I am now trying to clean up some error management code. By the time being, when I detect an error, I just do a “Debug.print” and return an empty array. Could you point me out to some examples to learn how to properly do error management for a new Motoko library?
Is it an unexpected, unrecoverable error? Then Debug.trap is a good choice.
Is it an error that you expect the user of your library to handle? Then maybe Result<T, Text> might be the best choice? (Even if ergonomics are still limited until ?-syntax is available for not just the ?-type, but also Result).
Yes, it is an error that can be expected by the user of the library. For instance, a decoding error of an illegal base58 string.
So, in case there is an error, should I return the text error in the “Text” field? If there is no error, should I leave the “Text” empty so the user can check it?
The Result type is just a variant type, in Joachim’s example success in your code would return #ok(T) and an error would return #err(Text).
If type T here were a Nat, you might return #ok(10) and there would be no Text involved. If you return an error, you could return #err(“Illegal base58 string”) , this is where the Text is used.
You could make a DecodeError type instead of using Text, eg:
type DecodeError = {
#illegalBase58String;
#illegalSomethingElse;
#anotherError;
}
Then your result could be Result<Nat, DecodeError> where success returns #ok(10) and failure might return #err(#illegalBase58String) .
This way a user of the library could handle the DecodeError type explicitly.