std.exception
This module defines functions related to exceptions and general error
handling. It also defines functions intended to aid in unit testing.
Synopsis of some of std.
exception's functions:
string synopsis()
{
FILE* f = enforce(fopen("some/file"));
FILE* g = enforceEx!WriteException(fopen("some/other/file", "w"));
Exception e = collectException(write(g, readln(f)));
if (e)
{
... an exception occurred...
... We have the exception to play around with...
}
string msg = collectExceptionMsg(write(g, readln(f)));
if (msg)
{
... an exception occurred...
... We have the message from the exception but not the exception...
}
char[] line;
enforce(readln(f, line));
return assumeUnique(line);
}
License:Boost License 1.0
Authors:Andrei Alexandrescu and Jonathan M Davis
Source:
std/exception.d
- void assertNotThrown(T : Throwable = Exception, E)(lazy E expression, string msg = null, string file = __FILE__, size_t line = __LINE__);
- Asserts that the given expression does not throw the given type
of Throwable. If a Throwable of the given type is thrown,
it is caught and does not escape assertNotThrown. Rather, an
AssertError is thrown. However, any other Throwables will escape.
Parameters:
T |
The Throwable to test for. |
E expression |
The expression to test. |
string msg |
Optional message to output on test failure.
If msg is empty, and the thrown exception has a
non-empty msg field, the exception's msg field
will be output on test failure. |
string file |
The file where the error occurred.
Defaults to __FILE__. |
size_t line |
The line where the error occurred.
Defaults to __LINE__. |
Throws:
AssertError if the given Throwable is thrown.
Examples:
assertNotThrown!StringException(enforceEx!StringException(true, "Error!"));
assertNotThrown(enforceEx!StringException(true, "Error!"));
assert(collectExceptionMsg!AssertError(assertNotThrown!StringException(
enforceEx!StringException(false, "Error!"))) ==
`assertNotThrown failed: StringException was thrown: Error!`);
- void assertThrown(T : Throwable = Exception, E)(lazy E expression, string msg = null, string file = __FILE__, size_t line = __LINE__);
- Asserts that the given expression throws the given type of Throwable.
The Throwable is caught and does not escape assertThrown. However,
any other Throwables will escape, and if no Throwable
of the given type is thrown, then an AssertError is thrown.
Parameters:
T |
The Throwable to test for. |
E expression |
The expression to test. |
string msg |
Optional message to output on test failure. |
string file |
The file where the error occurred.
Defaults to __FILE__. |
size_t line |
The line where the error occurred.
Defaults to __LINE__. |
Throws:
AssertError if the given Throwable is not thrown.
Examples:
assertThrown!StringException(enforceEx!StringException(false, "Error!"));
assertThrown(enforceEx!StringException(false, "Error!"));
assert(collectExceptionMsg!AssertError(assertThrown!StringException(
enforceEx!StringException(true, "Error!"))) ==
`assertThrown failed: No StringException was thrown.`);
- T enforce(T)(T value, lazy const(char)[] msg = null, string file = __FILE__, size_t line = __LINE__) if (is(typeof(()
{
if (!value)
{
}
}
)));
- If !!value is true, value is returned. Otherwise,
new Exception(msg) is thrown.
Note:
enforce is used to throw exceptions and is therefore intended to
aid in error handling. It is not intended for verifying the logic
of your program. That is what assert is for. Also, do not use
enforce inside of contracts (i.e. inside of in and out
blocks and invariants), because they will be compiled out when
compiling with -release. Use assert in contracts.
Example:
auto f = enforce(fopen("data.txt"));
auto line = readln(f);
enforce(line.length, "Expected a non-empty line.");
- T enforce(T, string file, size_t line = __LINE__)(T value, lazy const(char)[] msg = null) if (is(typeof(()
{
if (!value)
{
}
}
)));
- Deprecated. If passing the file or line number explicitly, please use
the overload of enforce which takes them as function arguments. Taking
them as template arguments causes unnecessary template bloat. This
overload will be removed in June 2015.
- T enforce(T, Dg, string file = __FILE__, size_t line = __LINE__)(T value, scope Dg dg) if (isSomeFunction!Dg && is(typeof(dg())) && is(typeof(()
{
if (!value)
{
}
}
)));
- If !!value is true, value is returned. Otherwise, the given
delegate is called.
The whole safety and purity are inferred from Dg's safety and purity.
- T enforce(T)(T value, lazy Throwable ex);
- If !!value is true, value is returned. Otherwise, ex is thrown.
Example:
auto f = enforce(fopen("data.txt"));
auto line = readln(f);
enforce(line.length, new IOException);
- T errnoEnforce(T, string file = __FILE__, size_t line = __LINE__)(T value, lazy string msg = null);
- If !!value is true, value is returned. Otherwise,
new ErrnoException(msg) is thrown. ErrnoException assumes that the
last operation set errno to an error code.
Example:
auto f = errnoEnforce(fopen("data.txt"));
auto line = readln(f);
enforce(line.length);
- template enforceEx(E : Throwable) if (is(typeof(new E("", "std/exception.d", 541))))
template enforceEx(E : Throwable) if (is(typeof(new E("std/exception.d", 553))) && !is(typeof(new E("", "std/exception.d", 553))))
- If !!value is true, value is returned. Otherwise,
new E(msg, file, line) is thrown. Or if E doesn't take a message
and can be constructed with new E(file, line), then
new E(file, line) will be thrown.
Example:
auto f = enforceEx!FileMissingException(fopen("data.txt"));
auto line = readln(f);
enforceEx!DataCorruptionException(line.length);
- T enforceEx(T)(T value, lazy string msg = "", string file = __FILE__, size_t line = __LINE__);
- Ditto
- T collectException(T = Exception, E)(lazy E expression, ref E result);
- Catches and returns the exception thrown from the given expression.
If no exception is thrown, then null is returned and result is
set to the result of the expression.
Note that while collectException can be used to collect any
Throwable and not just Exceptions, it is generally ill-advised to
catch anything that is neither an Exception nor a type derived from
Exception. So, do not use collectException to collect
non-Exceptions unless you're sure that that's what you really want to
do.
Parameters:
T |
The type of exception to catch. |
E expression |
The expression which may throw an exception. |
E result |
The result of the expression if no exception is thrown. |
Examples:
int b;
int foo() { throw new Exception("blah"); }
assert(collectException(foo(), b));
int[] a = new int[3];
import core.exception : RangeError;
assert(collectException!RangeError(a[4], b));
- T collectException(T : Throwable = Exception, E)(lazy E expression);
- Catches and returns the exception thrown from the given expression.
If no exception is thrown, then null is returned. E can be
void.
Note that while collectException can be used to collect any
Throwable and not just Exceptions, it is generally ill-advised to
catch anything that is neither an Exception nor a type derived from
Exception. So, do not use collectException to collect
non-Exceptions unless you're sure that that's what you really want to
do.
Parameters:
T |
The type of exception to catch. |
E expression |
The expression which may throw an exception. |
- string collectExceptionMsg(T = Exception, E)(lazy E expression);
- Catches the exception thrown from the given expression and returns the
msg property of that exception. If no exception is thrown, then null is
returned. E can be void.
If an exception is thrown but it has an empty message, then
emptyExceptionMsg is returned.
Note that while collectExceptionMsg can be used to collect any
Throwable and not just Exceptions, it is generally ill-advised to
catch anything that is neither an Exception nor a type derived from
Exception. So, do not use collectExceptionMsg to collect
non-Exceptions unless you're sure that that's what you really want to
do.
Parameters:
T |
The type of exception to catch. |
E expression |
The expression which may throw an exception. |
Examples:
void throwFunc() { throw new Exception("My Message."); }
assert(collectExceptionMsg(throwFunc()) == "My Message.");
void nothrowFunc() {}
assert(collectExceptionMsg(nothrowFunc()) is null);
void throwEmptyFunc() { throw new Exception(""); }
assert(collectExceptionMsg(throwEmptyFunc()) == emptyExceptionMsg);
- string emptyExceptionMsg;
- Value that collectExceptionMsg returns when it catches an exception
with an empty exception message.
- pure nothrow immutable(T)[] assumeUnique(T)(T[] array);
pure nothrow immutable(T)[] assumeUnique(T)(ref T[] array);
- Casts a mutable array to an immutable array in an idiomatic
manner. Technically, assumeUnique just inserts a cast,
but its name documents assumptions on the part of the
caller. assumeUnique(arr) should only be called when
there are no more active mutable aliases to elements of arr. To strengthen this assumption, assumeUnique(arr)
also clears arr before returning. Essentially assumeUnique(arr) indicates commitment from the caller that there
is no more mutable access to any of arr's elements
(transitively), and that all future accesses will be done through
the immutable array returned by assumeUnique.
Typically, assumeUnique is used to return arrays from
functions that have allocated and built them.
Example:
string letters()
{
char[] result = new char['z' - 'a' + 1];
foreach (i, ref e; result)
{
e = cast(char)('a' + i);
}
return assumeUnique(result);
}
The use in the example above is correct because result
was private to letters and is inaccessible in writing
after the function returns. The following example shows an
incorrect use of assumeUnique.
Bad:
private char[] buffer;
string letters(char first, char last)
{
if (first >= last) return null; auto sneaky = buffer;
sneaky.length = last - first + 1;
foreach (i, ref e; sneaky)
{
e = cast(char)('a' + i);
}
return assumeUnique(sneaky); }
The example above wreaks havoc on client code because it is
modifying arrays that callers considered immutable. To obtain an
immutable array from the writable array buffer, replace
the last line with:
return to!(string)(sneaky);
The call will duplicate the array appropriately.
Note that checking for uniqueness during compilation is
possible in certain cases, especially when a function is
marked as a pure function. The following example does not
need to call assumeUnique because the compiler can infer the
uniqueness of the array in the pure function:
string letters() pure
{
char[] result = new char['z' - 'a' + 1];
foreach (i, ref e; result)
{
e = cast(char)('a' + i);
}
return result;
}
For more on infering uniqueness see the unique and
lent keywords in the
ArchJava
language.
The downside of using assumeUnique's
convention-based usage is that at this time there is no
formal checking of the correctness of the assumption;
on the upside, the idiomatic use of assumeUnique is
simple and rare enough to be tolerable.
- nothrow T assumeWontThrow(T)(lazy T expr, string msg = null, string file = __FILE__, size_t line = __LINE__);
- Wraps a possibly-throwing expression in a nothrow wrapper so that it
can be called by a nothrow function.
This wrapper function documents commitment on the part of the caller that
the appropriate steps have been taken to avoid whatever conditions may
trigger an exception during the evaluation of expr. If it turns out
that the expression does throw at runtime, the wrapper will throw an
AssertError.
(Note that Throwable objects such as AssertError that do not
subclass Exception may be thrown even from nothrow functions,
since they are considered to be serious runtime problems that cannot be
recovered from.)
Examples:
import std.math : sqrt;
int squareRoot(int x)
{
if (x < 0)
throw new Exception("Tried to take root of negative number");
return cast(int)sqrt(cast(double)x);
}
int computeLength(int x, int y) nothrow
{
return assumeWontThrow(squareRoot(x*x + y*y));
}
assert(computeLength(3, 4) == 5);
- pure nothrow @trusted bool doesPointTo(S, T, Tdummy = void)(auto ref const S source, ref const T target) if (__traits(isRef, source) || isDynamicArray!S || isPointer!S || is(S == class));
- The "pointsTo" functions, doesPointTo and mayPointTo.
Returns true if source's representation embeds a pointer
that points to target's representation or somewhere inside
it.
If source is or contains a dynamic array, then, then these functions will check
if there is overlap between the dynamic array and target's representation.
If source is a class, then pointsTo will handle it as a pointer.
If target is a pointer, a dynamic array or a class, then these functions will only
check if source points to target, not what target references.
If source is or contains a union, then there may be either false positives or
false negatives:
doesPointTo will return true if it is absolutly certain
source points to target. It may produce false negatives, but never
false positives. This function should be prefered when trying to validate
input data.
mayPointTo will return false if it is absolutly certain
source does not point to target. It may produce false positives, but never
false negatives. This function should be prefered for defensively choosing a
code path.
Note:
Evaluating pointsTo(x, x) checks whether x has
internal pointers. This should only be done as an assertive test,
as the language is free to assume objects don't have internal pointers
(TDPL 7.1.3.5).
- class ErrnoException: object.Exception;
- Thrown if errors that set errno occur.
- CommonType!(T1, T2) ifThrown(E : Throwable = Exception, T1, T2)(lazy scope T1 expression, lazy scope T2 errorHandler);
CommonType!(T1, T2) ifThrown(E : Throwable, T1, T2)(lazy scope T1 expression, scope T2 delegate(E) errorHandler);
CommonType!(T1, T2) ifThrown(T1, T2)(lazy scope T1 expression, scope T2 delegate(Exception) errorHandler);
- 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.
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. |
T1 expression |
The expression to run and return its result. |
T2 errorHandler |
The handler to run if the expression throwed. |
Examples:
assert("x".to!int().ifThrown(0) == 0);
You can also chain multiple calls to ifThrown, each capturing errors from the
entire preceding expression.
Example:
string s="true";
assert(s.to!int().
ifThrown(cast(int)s.to!double()).
ifThrown(cast(int)s.to!bool())
== 1);
assert(enforce("x".to!int() < 1).to!string()
.ifThrown!ConvException("not a number")
.ifThrown!Exception("number too small")
== "not a number");
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.
Examples:
static assert(is(typeof(null.ifThrown(new Object())) == Object));
static assert(is(typeof((new Object()).ifThrown(null)) == Object));
static assert(!__traits(compiles, 1.ifThrown(new Object())));
static assert(!__traits(compiles, (new Object()).ifThrown(1)));
If you need to use the actual thrown exception, you can use a delegate.
Example:
assert("%s".format().ifThrown!Exception(e => e.classinfo.name) == "std.format.FormatException");