[Ballerina] Error Handling — Part III — Error Binding Patterns
In the previous posts we looked into the concept of errors in Ballerina and related actions.
- Part I — introduction to the error type and
check
,panic
,checkpanic
andtrap
. - Part II — user-defined errors, immutability, type test, etc.
In this post we will be looking at error binding patterns.
Error Binding Patterns
Binding patterns in Ballerina can be used to destructure a structured value (such as a mapping, list, or an error) into separate variables at the same time (i. e., single line).
The “Binding Patterns” section of Ballerina by Example includes examples for all of the possible binding patterns.
There are two kinds of error binding patterns.
- direct error binding pattern
- indirect error binding pattern
Direct Error Binding Pattern
A direct error binding pattern is where the generic error
type is used (similar to the direct error constructor).
While all the fields of the error can be accessed via the .reason()
and .detail()
methods on an error value (L40 — L43), destructuring binding patterns allow us to do this in one line (L55).
If a direct error binding pattern has binding patterns, the first has to be a simple binding pattern and the subsequent binding patterns, if any, need to be named arg binding patterns, except for a rest binding pattern which can be specified as the last pattern.
An error binding pattern can have a rest binding pattern which just creates a map with all the detail fields that were not assigned to variables explicitly.
Thus, the following are all valid direct error binding patterns.
error(errReason2) = res;
error(errReason2, message = errMessage2) = res;
error(errReason2, message = errMessage2, ...rest) = res;
error(_, message = errMessage2, code = errCode2) = res;
A direct error binding pattern can be used with any error value, including those of a user-defined error type.
While we assign the reason to a variable when destructuring, it seems a bit redundant, since we know it will always be “MyReason”, if the error value is of type MyError
.
One thing we can do here is ignoring the reason using _
.
error(_, message = errMessage,
code = errCode, priority = errPriority) = res;
However that too feels like an overhead, given that we know what the value is and we just want to ignore it.
An indirect error binding pattern can be used in such a scenario.
Indirect Error Binding Pattern
An indirect error binding pattern is similar to a direct error binding pattern with the following exceptions.
- An error type reference (
MyError(..)
) is used instead oferror
(error(..)
). - There will be no simple binding pattern for the reason, and thus all the binding patterns have to be either named arg binding patterns or a rest binding pattern.
Note how the reason is not assigned to a variable now.
Error Typed Binding Patterns
Ballerina allows combining a type descriptor or var and a binding pattern to define and use the variables in line.
This allows us to directly define the variables when destructuring a value, instead of first defining the variables and then using them.
That’s it for error binding patterns! In the next post, we will be looking at error match patterns.
Thanks!