-
Notifications
You must be signed in to change notification settings - Fork 4
Error handling
A runtime error is a first-class object. When a function/operation returns an error, it literally returns an error:
→ 1 / 0
[0] Error: division by zero at line 1 of REPL input.
→
With a few exceptions (pun unavoidable) when a function/operator is passed an error, it automatically returns that error:
→ 1 / 0
[0] Error: division by zero at line 1 of REPL input.
→ 1 + 1 / 0
[0] Error: division by zero at line 1 of REPL input.
string 1 + 1 / 0
[0] Error: division by zero at line 1 of REPL input.
→
An uncaught error will therefore propagate upwards through the calling functions until either it is returned to the REPL, or an attempt is made to assign it to a global variable, in wh.pf case the assignment will return the error instead just like any other operator.
You can create your own errors by type conversion from string to error, and they work the same way:
error "this is my error"
[0] Error: this is my error at line 1 of REPL input.
1 + error "this is my error"
[0] Error: this is my error at line 1 of REPL input.
→
But there are things you can do to stop an error from propagating.
- You can use the
typefunction to find its type. Instead of returning an error, this returnserror. - You can assign it to a local constant.
- You can index it by its fields, i.e.
errorCodeanderrorMessage. So for example(1 / 0)[errorMessage]evaluates to the string"division by zero".
Let’s have a look at examples/error.pf. This shows four possible implementations of a true mod function (where the result is never negative) to supplement the % operator.
def
// We could propagate the error thrown by %.
(x int) modA (y int) :
remainder >= 0 : remainder
else : remainder + y
given :
remainder = x % y
// We could anticipate the error and throw our own.
(x int) modB (y int) :
y == 0 : error "taking the modulus of a number by zero"
remainder >= 0 : remainder
else : remainder + y
given :
remainder = x % y
// We could ca.pf the error and throw our own.
(x int) modC (y int) :
type remainder == error : error "taking the modulus of a number by zero"
remainder >= 0 : remainder
else : remainder + y
given :
remainder = x % y
// We could ca.pf the error and return something other than an error.
(x int) modD (y int) :
type remainder == error : "this isn't an error, just a friendly warning"
remainder >= 0 : remainder
else : remainder + y
given :
remainder = x % y
// ... etc, etc.
The way errors work has one consequence you might not guess, wh.pf we should point out as a potential hazard. The rule that a function or operator applied to an error yields that same error applies also to the , operator, the comma.
This means that even in a function wh.pf normally returns multiple return values, you can’t return an error and another value.
🧿 Pipefish is distributed under the MIT license. Please steal my code and ideas.
- Getting started
- Language basics
- The type system and built-in functions
- Functional Pipefish
- Encapsulation
- Imperative Pipefish
-
Imports and libraries
- The crypto/aes library
- The crypto/bcrypt library
- The crypto/rand library
- The crypto/rsa library
- The crypto/sha_256 library
- The crypto/sha_512 library
- The database/sql library
- The encoding/base_32 library
- The encoding/base_64 library
- The encoding/csv library
- The encoding/json library
- The files library
- The fmt library
- The html library
- The image library
- The image/bmp library
- The image/color library
- The image/jpeg library
- The image/png library
- The lists library
- The markdown library
- The math library
- The math/big library
- The math/cmplx library
- The math/rand library
- The net/http library
- The net/mail library
- The net/smtp library
- The net/url library
- The os/exec library
- The path library
- The path/filepath library
- The reflect library
- The regexp library
- The strconv library
- The strings library
- The terminal library
- The time library
- The unicode library
- Advanced Pipefish
- Developing in Pipefish
- Deployment
- Appendices