Skip to content
Christopher Ross-Gill edited this page Aug 1, 2016 · 1 revision

R3 contains several changes to the ERROR! datatype.

Table of Contents

Disarmed by Default

Errors are disarmed by default. That means they act like other datatypes that are non-active in evaluation.

For example, in R2, the code:

result: try block
if error? result [print result]

would need to be written as:

result: try block
if error? :result [print disarm :result]

The the get-word references and DISARM are required to prevent the error from being thrown again.

In R3, that is no longer required. Errors are like objects, they evaluate to themselves and will not throw simply on evaluation. This makes objects easier to use because you can pass them to functions, return them as results, and set them to variables without triggering exception handling.

So, in R3, the first example above will work fine.

Causing Errors

You can use DO to force error exception handling.

Extending the above example:

result: try block
if error? result [
    either result/type = 'math [do result][print result]
]

This code will cause the error if its of the math type, otherwise it will print the error to the console.

Backtrace

In R3, the WHERE field of an error provides a backtrace of the evaluation stack. This makes it easier to track down the location of errors, because you can see the other functions that were called:

Take this example:

divit: func [a b] [a / b]
divit 1 0
** Math error: Attempt to divide by zero
** Where: / divit
** Near: / b

The WHERE field shows the evaluation stack, indicating the error happened in / (divide) within the divit function.

This backtrace information is also available when you process an error with exception code:

err: try [divit 1 0]
probe err/where

Form Format

There are times when you want to catch an error and print it using the same "friendly" format used by the console. The FORM function will now do that. In addition, because PRINT uses FORM, you can also use PRINT for nicely formatted errors:

result: try [divit 1 0]
if error? result [print result halt]

On an error, you will see the result:

** Math error: Attempt to divide by zero
** Where: / divit try
** Near: / b

Error Helper

If you want to construct an error value, you would normally define it like you would an object.

For example:

err: make error! [
    type: 'math
    id: 'zero-divide
    near: [here]
    where: [here]
]

But, in most code, you really don't want to go to that much work. Therefore, we provide the CAUSE-ERROR helper function:

cause-error 'math 'zero-divide none

If the error requires arguments, use a block for the last parameter:

cause-error 'access 'cannot-open [file-name]
Clone this wiki locally