Errors in Julia

In Julia, it’s idiomatic to communicate errors via exceptions, which is different from the approach used in some other languages. Julia’s approach allows for structured error handling using try-catch blocks.

using Exceptions

# By convention, functions that can fail should be named with a trailing !
function f!(arg::Int)
    if arg == 42
        # throw constructs an exception with the given error message
        throw(ErrorException("can't work with 42"))
    end
    
    # Return the result if no error occurred
    return arg + 3
end

# Custom exceptions can be defined as subtypes of Exception
struct OutOfTeaError <: Exception end
struct PowerError <: Exception end

function make_tea!(arg::Int)
    if arg == 2
        throw(OutOfTeaError())
    elseif arg == 4
        # We can wrap errors by catching and re-throwing with additional context
        try
            throw(PowerError())
        catch e
            throw(ErrorException("making tea: $e"))
        end
    end
    # No error occurred
    return nothing
end

function main()
    for i in [7, 42]
        # It's common to use try-catch blocks for error handling
        try
            r = f!(i)
            println("f worked: $r")
        catch e
            println("f failed: $e")
        end
    end

    for i in 0:4
        try
            make_tea!(i)
            println("Tea is ready!")
        catch e
            if e isa OutOfTeaError
                println("We should buy new tea!")
            elseif e isa PowerError || (e isa ErrorException && occursin("PowerError", e.msg))
                println("Now it is dark.")
            else
                println("unknown error: $e")
            end
        end
    end
end

main()

This script demonstrates error handling in Julia:

  1. We define a function f! that may throw an exception.

  2. We define custom exception types OutOfTeaError and PowerError.

  3. The make_tea! function demonstrates throwing different types of errors.

  4. In the main function, we use try-catch blocks to handle potential errors.

  5. We use isa to check the type of caught exceptions, which is similar to the errors.Is function in some other languages.

  6. For wrapped errors, we can check the error message using occursin.

When you run this script, you should see output similar to:

f worked: 10
f failed: ErrorException("can't work with 42")
Tea is ready!
Tea is ready!
We should buy new tea!
Tea is ready!
Now it is dark.

This example showcases Julia’s exception handling mechanisms, including throwing and catching exceptions, defining custom exception types, and handling different error scenarios.