ifThrown

ML-style functional exception handling. Runs the supplied expression and returns its result. If the expression throws a Throwable, runs the supplied error handler instead and return its result. The error handler's type must be the same as the expression's type.

  1. CommonType!(T1, T2) ifThrown(T1 expression, T2 errorHandler)
    CommonType!(T1, T2)
    ifThrown
    (
    E : Throwable = Exception
    T1
    T2
    )
    (
    lazy scope T1 expression
    ,
    lazy scope T2 errorHandler
    )
  2. CommonType!(T1, T2) ifThrown(T1 expression, T2 delegate(E) errorHandler)
  3. CommonType!(T1, T2) ifThrown(T1 expression, T2 delegate(Exception) errorHandler)

Parameters

E

The type of Throwables to catch. Defaults to Exception

T1

The type of the expression.

T2

The return type of the error handler.

expression T1

The expression to run and return its result.

errorHandler T2

The handler to run if the expression throwed.

Return Value

Type: CommonType!(T1, T2)

expression, if it does not throw. Otherwise, returns the result of errorHandler.

Examples

Revert to a default value upon an error:

import std.conv : to;
assert("x".to!int.ifThrown(0) == 0);

Chain multiple calls to ifThrown, each capturing errors from the entire preceding expression.

import std.conv : ConvException, to;
string s = "true";
assert(s.to!int.ifThrown(cast(int) s.to!double)
               .ifThrown(cast(int) s.to!bool) == 1);

s = "2.0";
assert(s.to!int.ifThrown(cast(int) s.to!double)
               .ifThrown(cast(int) s.to!bool) == 2);

// Respond differently to different types of errors
alias orFallback = (lazy a)  => a.ifThrown!ConvException("not a number")
                                 .ifThrown!Exception("number too small");

assert(orFallback(enforce("x".to!int < 1).to!string) == "not a number");
assert(orFallback(enforce("2".to!int < 1).to!string) == "number too small");

The expression and the errorHandler must have a common type they can both be implicitly casted to, and that type will be the type of the compound expression.

// null and new Object have a common type(Object).
static assert(is(typeof(null.ifThrown(new Object())) == Object));
static assert(is(typeof((new Object()).ifThrown(null)) == Object));

// 1 and new Object do not have a common type.
static assert(!__traits(compiles, 1.ifThrown(new Object())));
static assert(!__traits(compiles, (new Object()).ifThrown(1)));

Use a lambda to get the thrown object.

import std.format : format;
assert("%s".format.ifThrown!Exception(e => e.classinfo.name) == "std.format.FormatException");

Meta