Wolfram Language Paclet Repository

Community-contributed installable additions to the Wolfram Language

Primary Navigation

    • Cloud & Deployment
    • Core Language & Structure
    • Data Manipulation & Analysis
    • Engineering Data & Computation
    • External Interfaces & Connections
    • Financial Data & Computation
    • Geographic Data & Computation
    • Geometry
    • Graphs & Networks
    • Higher Mathematical Computation
    • Images
    • Knowledge Representation & Natural Language
    • Machine Learning
    • Notebook Documents & Presentation
    • Scientific and Medical Data & Computation
    • Social, Cultural & Linguistic Data
    • Strings & Text
    • Symbolic & Numeric Computation
    • System Operation & Setup
    • Time-Related Computation
    • User Interface Construction
    • Visualization & Graphics
    • Random Paclet
    • Alphabetical List
  • Using Paclets
    • Get Started
    • Download Definition Notebook
  • Learn More about Wolfram Language

ErrorTools

Guides

  • ErrorTools

Tech Notes

  • Error Handling with ErrorTools

Symbols

  • Raise
Error Handling with ErrorTools
Background & Motivation
Usage Conventions
Feature Overview
Putting It All Together: An Example Package Using ErrorTools
Wolfram/ErrorTools provides prototypes of new functions for constructing, throwing, and catching
Failure
[…]
-based representations of error conditions. This document describes how the functions in ErrorTools are intended to be used, as well as conventions for using them together.
EXPERIMENTAL: Wolfram/ErrorTools is an incubator for experimental functionality. Much or all of the functionality being prototyped in this paclet WILL change before a stable design is committed to.
Background & Motivation
ErrorTools is a product of a long-running design effort to improve error handling for large Wolfram Language projects. ErrorTools attempts to codify and generalize ad hoc error handling utility functions that have been independently reinvented across many large Wolfram Language packages. The functionality provided by ErrorTools should be usable by Wolfram Language programs ranging in size from large production-grade software to small one-off scripts or single-function packages.
Feature Overview
The sections below introduce and describe the main functionality provided by the ErrorTools package. Before proceeding, ensure that ErrorTools is loaded and visible by evaluating:
Needs["Wolfram`ErrorTools`"]

Throwing and Catching Failure[…] Objects

Raise
[tag
,
fmt,args…]
throw a
Failure
with the specified
tag
and formatted message
Handle
[expr,rules]
catch a
Failure
raised during the evaluation of
expr
that match
rules
CreateErrorType
[tag,expansions]
register an error tag for use with
Raise
, with optional "parent tag" expansions
Functions for throwing and catching
Failure
[…]
objects.
ErrorTools is designed to make it easy to use
Failure
[…]
objects as the representation of errors within a function or package. To support that goal, the
Raise
function makes it easy to both construct and throw a
Failure
[…]
in a single terse statement. Additionally, the corresponding Handle function makes it easy to conditionally catch thrown
Failure
objects.
Before we can use
Raise
and
Handle
, we need to register a failure tag to use in our
Failure
[…]
objects. A failure tag should identify the kind of error being represented:
In[35]:=
CreateErrorType[FileError,{}]
Now that we have an error tag registered, we can raise a failure—but without any handler, the failure reaches the top of the evaluation stack as an uncaught throw:
In[195]:=
Raise[FileError,"Something went wrong."]
Throw
:Uncaught ThrowFailure

Message:
Something went wrong.
Tag:
FileError
,$RaiseThrowTag returned to top level.
Out[195]=
HoldThrowFailure

Message:
Something went wrong.
Tag:
FileError
,$RaiseThrowTag
We can use Handle to catch raised failures. The second argument to Handle can be a pattern, and any
Failure
[…]
matching the pattern will be caught and returned:
In[193]:=
Handle[​​ Raise[FileError,"Something went wrong."],​​ _Failure​​]
Out[193]=
Failure

Message:
Something went wrong.
Tag:
FileError

Alternatively, passing a rule or list of rules as the second argument to Handle can be used to catch matching failures and then execute a custom action before returning:
In[194]:=
Handle[​​ Raise[FileError,"Something went wrong processing file"],​​ f:Failure[FileError,___]​​ Print["Caught failure: ",f];​​ Missing[]​​ ​​]
Caught failure: Failure

Message:
Something went wrong processing file
Tag:
FileError

Out[194]=
Missing[]
In general, any program using Raise should have corresponding Handle wrappers to prevent uncaught exceptions from escaping. In addition to the 2-argument forms, Handle also supports an operator form designed to be an easy-to-use annotation on functions using Raise internally:
Func[args] := Handle[_Failure] @ ...
The suggested usage convention for packages using Raise and Handle is designed to ensure that exceptions do not "escape" from within package code. The Usage Conventions section below describes this in further detail.

Composing Failure[…] Objects

WrapFailure
[failure,tag,fmt,args…]
constructs a new Failure with the specified
tag
and formatted message with a
"CausedBy"failure
field
WrapRaised
[tag,fmt,args…][expr]
wraps any uncaught
Failure
raised during the evaluation of expr in an outer
Failure
with the specified tag and formatted message, where the original raised
Failure
is the
"CausedBy"
field of the new error
Functions for composing Failure objects to give additional high-level context or low-level detail.

Failing Fast: Logic Error Functions

In larger software programs, especially in dynamic languages, it can often be useful to adopt a "defensive programming" writing style. ErrorTools provides specialized functions making it easy to check for and consistently handle common types of programming mistakes that are difficult to avoid at scale without static analysis.

Invalid Function Arguments

SetFallthroughError
set a "fallthrough" down value on a symbol raising a error when any unexpected arguments are applied
Functions for checking for common logic errors.
One of the most common types of logic error is calling a function with arguments that don't conform to any of the function definitions. SetFallthroughError makes it easy to add a definition to a function that handles the "fallthrough" case where no other function definitions expected the supplied arguments:
In[23]:=
SetFallthroughError[readConfigurationValue]​​​​readConfigurationValue[config_?AssociationQ,key_?StringQ]:=Module[{},​​ Lookup[config,key]​​]
Now lets try using readConfigurationValue as it expects to be used:
In[27]:=
config="CacheSize"10;
In[28]:=
readConfigurationValue[config,"CacheSize"]
Out[28]=
10
But what happens if somewhere in our code, we accidentally call readConfigurationValue with a different set of argument types? (This can happen easily if, for example, an earlier version of readConfigurationValue had a different signature, and that call site mistakenly not updated after a refactoring.) Let's see:
In[29]:=
readConfigurationValue[{{"CacheSize",10}},"CacheSize"]
Throw
:Uncaught Throw[Failure[DownValueFallthroughError,SymbolreadConfigurationValue,ArgumentListHoldComplete[{{{CacheSize,10}},CacheSize}],MessageTemplateArguments applied to symbol `` did not match any DownValues.,MessageParameters{readConfigurationValue}],$RaiseThrowTag] returned to top level.
Out[29]=
HoldThrowFailure

Message:
Arguments applied to symbol
readConfigurationValue
did not match any DownValues.
Tag:
DownValueFallthroughError
,$RaiseThrowTag
Our program now fails with a clear message telling us that a function was called with unexpected arguments. A well-behaved public function should catch this exception from the internal readConfigurationValue before it reaches the user as an uncaught exception.
It is important to note that
SetFallthroughError
is primarily intended to aid in catching programmer mistakes early, before a piece of software reaches the end user—it is very useful during development when function are being refactored and changed rapidly, but should not be relied upon for reporting anticipated errors. Resorting to an error created by
SetFallthroughError
should be a last line of defense for ensuring an orderly (if abrupt) end to a program running in a state the programmer didn't anticipate. But it is not a replacement for more user-friendly argument checking and error reporting logic that should always be done first.

Unexpected Program Conditions

RaiseAssert
[cond,fmt,args…]
If
cond
is not True, raises a
Failure
with the formatted message
ConfirmReplace
[expr,rules]
applies a rule or list of rules in an attempt to transform the entire expression
expr
, and raises an error if no rule matches
RaiseConfirm[expr]
If expr evaluates to a Failure[…] or other error-like value, raise it as an exception
Functions for checking for logic error conditions.
Usage Conventions

Background: Returning Errors vs. Throwing Errors

Why Wolfram Language Functions Return Errors

Wolfram Language has long provided mechanisms for non-locally altering control flow, for example via
Throw
and
Catch
. However, an important and rigidly-adhered-to convention of all System`-level functions (with the exception of control-flow functions themselves) is that they always return normally, and do not initiate uncaught exceptions or aborts. Returning instead of throwing is especially important behavior when considering interactive use of Wolfram Language, where any uncaught throw might destroy useful context for the user about where an issue occurred, or prevent them from continuing a computation with partial results:
In[241]:=
Map[​​ Import,​​ {"ExampleData/gear.1","ExampleData/gear.2","ExampleData/gear.7"} ​​]
Import
:File ExampleData/gear.7 not found during Import.
Out[241]=

,
,$Failed
If Import threw an exception instead of returning, the user would not be able to use the two values that did succeed, and would have a harder time seeing that it was the third element that failed.

The Cost Of Returning Errors

However, treating errors as normal values to be returned alongside "valid" values comes with a cognitive and syntactic overhead: any function call that might return an error must be wrapped in extra logic to treat error values differently from valid values. Without prompt and attentive handling, an error value assumed to be a valid value can turn into a cascade of subsequent spurious errors:
In[212]:=
Map[FromDigits,StringSplit[ReadString["doesnotexist.txt"]]]
OpenRead
:Cannot open doesnotexist.txt.
StringSplit
:String or list of strings expected at position 1 in StringSplit[$Failed].
FromDigits
:The expression $Failed is not a list of digits or a string of valid digits.
StringSplit
:String or list of strings expected at position 1 in StringSplit[FromDigits[$Failed]].
Out[212]=
StringSplit[FromDigits[$Failed]]
This overhead is especially pronounced in large Wolfram Language projects, where errors occurring in lower-level functions need to travel far up the call stack before they reach the end user, imposing a burden on every intermediate function. The solution used by many large Wolfram Language programs (as well as in many programming languages) is to adopt exceptions as a means to separate error propagation control flow from the "happy path" logic. Propagating errors using non-local control flow helps keep code readable and maintainable.

Errors in Public vs Private Functions

ErrorTools is designed to make it easy to balance the "errors-as-return-values" model with the "errors-as-exceptions". The suggested convention is that:
◼
  • Public functions should always return their errors normally.
  • ◼
  • Private ("internal") functions should always throw their errors. Only valid values should be returned normally.
  • Putting It All Together: An Example Package Using ErrorTools
    The example program below demonstrates:
    ◼
  • A public function that catches any Failure objects thrown from its internal package code
  • ◼
  • A private function that freely throws exceptions, expecting them to be caught in the public-facing function before being returned to the caller
  • ◼
  • Composing lower-level failures and higher-level failures to provide both a high-level description to the user of what went wrong, as well as a low-level "paper trail" that can be expanded for further detail.
  • Example Package

    Helper Functions

    Using GetTuples

    Create a file containing a valid form of our data:
    Use GetTuples to read that data. As expected it correctly returns a valid value:
    But what happens if the file contains data that isn't in quite the right format? In that case, we get a failure describing both at a high-level what went wrong ("Unable to read tuples from file"), as well as the lower-level "cause" of that failure ("Entry on line 3 did not have the expected form"):
    Additionally, we also get a descriptive error if we pass GetTuples a file that doesn't even exist:

    © 2025 Wolfram. All rights reserved.

    • Legal & Privacy Policy
    • Contact Us
    • WolframAlpha.com
    • WolframCloud.com