// Written in the D programming language. /++ This module defines functions related to exceptions and general error handling. It also defines functions intended to aid in unit testing. $(SCRIPT inhibitQuickIndex = 1;)$(DIVC quickindex,$(BOOKTABLE,$(TR $(TH Category) $(TH Functions))$(TR $(TD Assumptions) $(TD $(LREF assertNotThrown) $(LREF assertThrown) $(LREF assumeUnique) $(LREF assumeWontThrow) $(LREF mayPointTo)))$(TR $(TD Enforce) $(TD $(LREF doesPointTo) $(LREF enforce) $(LREF errnoEnforce)))$(TR $(TD Handlers) $(TD $(LREF collectException) $(LREF collectExceptionMsg) $(LREF ifThrown) $(LREF handle)))$(TR $(TD Other) $(TD $(LREF basicExceptionCtors) $(LREF emptyExceptionMsg) $(LREF ErrnoException) $(LREF RangePrimitive))))) Copyright: Copyright Andrei Alexandrescu 2008-, Jonathan M Davis 2011-. License: $(HTTP boost.org/LICENSE_1_0.txt, Boost License 1.0) Authors: $(HTTP erdani.org, Andrei Alexandrescu) and $(HTTP jmdavisprog.com, Jonathan M Davis) Source: $(PHOBOSSRC std/exception.d) +/module std.exception; /// Synopis@system unittest{ import core.stdc.stdlib : malloc, free; import std.algorithm.comparison : equal; import std.algorithm.iteration : map, splitter; import std.algorithm.searching : endsWith; import std.conv : ConvException, to; import std.range : front, retro; // use enforce like assert int a = 3; enforce(a > 2, "a needs to be higher than 2."); // enforce can throw a custom exception enforce!ConvException(a > 2, "a needs to be higher than 2."); // enforce will return it's input enum size = 42; auto memory = enforce(malloc(size), "malloc failed")[0 .. size]; scope(exit) free(memory.ptr); // collectException can be used to test for exceptions Exception e = collectException("abc".to!int); assert(e.file.endsWith("conv.d")); // and just for the exception message string msg = collectExceptionMsg("abc".to!int); assert(msg == "Unexpected 'a' when converting from type string to type int"); // assertThrown can be used to assert that an exception is thrown assertThrown!ConvException("abc".to!int); // ifThrown can be used to provide a default value if an exception is thrown assert("x".to!int().ifThrown(0) == 0); // handle is a more advanced version of ifThrown for ranges auto r = "12,1337z32,54".splitter(',').map!(a => to!int(a)); auto h = r.handle!(ConvException, RangePrimitive.front, (e, r) => 0); assert(h.equal([12, 0, 54])); assertThrown!ConvException(h.retro.equal([54, 0, 12])); // basicExceptionCtors avoids the boilerplate when creating custom exceptions static class MeaCulpa : Exception { mixin basicExceptionCtors; } e = collectException((){throw new MeaCulpa("diagnostic message");}()); assert(e.msg == "diagnostic message"); assert(e.file == __FILE__); assert(e.line == __LINE__ - 3); // assumeWontThrow can be used to cast throwing code into `nothrow` void exceptionFreeCode() nothrow { // auto-decoding only throws if an invalid UTF char is given assumeWontThrow("abc".front); } // assumeUnique can be used to cast mutable instance to an `immutable` one // use with care char[] str = " mutable".dup; str[0 .. 2] = "im"; immutable res = assumeUnique(str); assert(res == "immutable");} import std.range.primitives;import std.traits; /++ Asserts that the given expression does $(I 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 `Throwable`s will escape. Params: T = The `Throwable` to test for. expression = The expression to test. 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. file = The file where the error occurred. Defaults to `__FILE__`. line = The line where the error occurred. Defaults to `__LINE__`. Throws: `AssertError` if the given `Throwable` is thrown. Returns: the result of `expression`. +/auto assertNotThrown(T : Throwable = Exception, E) (lazy E expression, string msg = null, string file = __FILE__, size_t line = __LINE__){ import core.exception : AssertError; try { return expression(); } catch (T t) { immutable message = msg.length == 0 ? t.msg : msg; immutable tail = message.length == 0 ? "." : ": " ~ message; throw new AssertError("assertNotThrown failed: " ~ T.stringof ~ " was thrown" ~ tail, file, line, t); }}///@system unittest{ import core.exception : AssertError; import std.string; assertNotThrown!StringException(enforce!StringException(true, "Error!")); //Exception is the default. assertNotThrown(enforce!StringException(true, "Error!")); assert(collectExceptionMsg!AssertError(assertNotThrown!StringException( enforce!StringException(false, "Error!"))) == `assertNotThrown failed: StringException was thrown: Error!`);}@system unittest{ import core.exception : AssertError; import std.string; assert(collectExceptionMsg!AssertError(assertNotThrown!StringException( enforce!StringException(false, ""), "Error!")) == `assertNotThrown failed: StringException was thrown: Error!`); assert(collectExceptionMsg!AssertError(assertNotThrown!StringException( enforce!StringException(false, ""))) == `assertNotThrown failed: StringException was thrown.`); assert(collectExceptionMsg!AssertError(assertNotThrown!StringException( enforce!StringException(false, ""), "")) == `assertNotThrown failed: StringException was thrown.`);} @system unittest{ import core.exception : AssertError; static noreturn throwEx(Throwable t) { throw t; } bool nothrowEx() { return true; } try { assert(assertNotThrown!Exception(nothrowEx())); } catch (AssertError) assert(0); try { assert(assertNotThrown!Exception(nothrowEx(), "It's a message")); } catch (AssertError) assert(0); try { assert(assertNotThrown!AssertError(nothrowEx())); } catch (AssertError) assert(0); try { assert(assertNotThrown!AssertError(nothrowEx(), "It's a message")); } catch (AssertError) assert(0); { bool thrown = false; try { assertNotThrown!Exception( throwEx(new Exception("It's an Exception"))); } catch (AssertError) thrown = true; assert(thrown); } { bool thrown = false; try { assertNotThrown!Exception( throwEx(new Exception("It's an Exception")), "It's a message"); } catch (AssertError) thrown = true; assert(thrown); } { bool thrown = false; try { assertNotThrown!AssertError( throwEx(new AssertError("It's an AssertError", __FILE__, __LINE__))); } catch (AssertError) thrown = true; assert(thrown); } { bool thrown = false; try { assertNotThrown!AssertError( throwEx(new AssertError("It's an AssertError", __FILE__, __LINE__)), "It's a message"); } catch (AssertError) thrown = true; assert(thrown); }} /++ Asserts that the given expression throws the given type of `Throwable`. The `Throwable` is caught and does not escape assertThrown. However, any other `Throwable`s $(I will) escape, and if no `Throwable` of the given type is thrown, then an `AssertError` is thrown. Params: T = The `Throwable` to test for. expression = The expression to test. msg = Optional message to output on test failure. file = The file where the error occurred. Defaults to `__FILE__`. line = The line where the error occurred. Defaults to `__LINE__`. Throws: `AssertError` if the given `Throwable` is not thrown. +/void assertThrown(T : Throwable = Exception, E) (lazy E expression, string msg = null, string file = __FILE__, size_t line = __LINE__){ import core.exception : AssertError; try expression(); catch (T) return; static if (!is(immutable E == immutable noreturn)) throw new AssertError("assertThrown failed: No " ~ T.stringof ~ " was thrown" ~ (msg.length == 0 ? "." : ": ") ~ msg, file, line);}///@system unittest{ import core.exception : AssertError; import std.string; assertThrown!StringException(enforce!StringException(false, "Error!")); //Exception is the default. assertThrown(enforce!StringException(false, "Error!")); assert(collectExceptionMsg!AssertError(assertThrown!StringException( enforce!StringException(true, "Error!"))) == `assertThrown failed: No StringException was thrown.`);} @system unittest{ import core.exception : AssertError; static noreturn throwEx(Throwable t) { throw t; } void nothrowEx() { } try { assertThrown!Exception(throwEx(new Exception("It's an Exception"))); } catch (AssertError) assert(0); try { assertThrown!Exception(throwEx(new Exception("It's an Exception")), "It's a message"); } catch (AssertError) assert(0); try { assertThrown!AssertError(throwEx(new AssertError("It's an AssertError", __FILE__, __LINE__))); } catch (AssertError) assert(0); try { assertThrown!AssertError(throwEx(new AssertError("It's an AssertError", __FILE__, __LINE__)), "It's a message"); } catch (AssertError) assert(0); { bool thrown = false; try assertThrown!Exception(nothrowEx()); catch (AssertError) thrown = true; assert(thrown); } { bool thrown = false; try assertThrown!Exception(nothrowEx(), "It's a message"); catch (AssertError) thrown = true; assert(thrown); } { bool thrown = false; try assertThrown!AssertError(nothrowEx()); catch (AssertError) thrown = true; assert(thrown); } { bool thrown = false; try assertThrown!AssertError(nothrowEx(), "It's a message"); catch (AssertError) thrown = true; assert(thrown); }} /++ Enforces that the given value is true. If the given value is false, an exception is thrown. The $(UL $(LI `msg` - error message as a `string`) $(LI `dg` - custom delegate that return a string and is only called if an exception occurred) $(LI `ex` - custom exception to be thrown. It is `lazy` and is only created if an exception occurred) ) Params: value = The value to test. E = Exception type to throw if the value evaluates to false. msg = The error message to put in the exception if it is thrown. dg = The delegate to be called if the value evaluates to false. ex = The exception to throw if the value evaluates to false. file = The source file of the caller. line = The line number of the caller. Returns: `value`, if `cast(bool) value` is true. Otherwise, depending on the chosen overload, `new Exception(msg)`, `dg()` or `ex` is thrown. $(PANEL $(NOTE `enforce` is used to throw exceptions and is therefore intended to aid in error handling. It is $(I not) intended for verifying the logic of your program - that is what `assert` is for.) Do not use `enforce` inside of contracts (i.e. inside of `in` and `out` blocks and `invariant`s), because contracts are compiled out when compiling with $(I -release). ) If a delegate is passed, the safety and purity of this function are inferred from `Dg`'s safety and purity. +/template enforce(E : Throwable = Exception)if (is(typeof(new E("", string.init, size_t.init)) : Throwable) || is(typeof(new E(string.init, size_t.init)) : Throwable)){ /// T enforce(T)(T value, lazy const(char)[] msg = null, string file = __FILE__, size_t line = __LINE__) if (is(typeof({ if (!value) {} }))) { if (!value) bailOut!E(file, line, msg); return value; }} /// dittoT 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) dg(); return value;} /// dittoT enforce(T)(T value, lazy Throwable ex){ if (!value) throw ex(); return value;} ///@system unittest{ import core.stdc.stdlib : malloc, free; import std.conv : ConvException, to; // use enforce like assert int a = 3; enforce(a > 2, "a needs to be higher than 2."); // enforce can throw a custom exception enforce!ConvException(a > 2, "a needs to be higher than 2."); // enforce will return it's input enum size = 42; auto memory = enforce(malloc(size), "malloc failed")[0 .. size]; scope(exit) free(memory.ptr);} ///@safe unittest{ assertNotThrown(enforce(true, new Exception("this should not be thrown"))); assertThrown(enforce(false, new Exception("this should be thrown")));} ///@safe unittest{ assert(enforce(123) == 123); try { enforce(false, "error"); assert(false); } catch (Exception e)Lines 1–500 of 2482. Load more
// Written in the D programming language. /++ This module defines functions related to exceptions and general error handling. It also defines functions intended to aid in unit testing. $(SCRIPT inhibitQuickIndex = 1;) $(DIVC quickindex, $(BOOKTABLE, $(TR $(TH Category) $(TH Functions)) $(TR $(TD Assumptions) $(TD $(LREF assertNotThrown) $(LREF assertThrown) $(LREF assumeUnique) $(LREF assumeWontThrow) $(LREF mayPointTo) )) $(TR $(TD Enforce) $(TD $(LREF doesPointTo) $(LREF enforce) $(LREF errnoEnforce) )) $(TR $(TD Handlers) $(TD $(LREF collectException) $(LREF collectExceptionMsg) $(LREF ifThrown) $(LREF handle) )) $(TR $(TD Other) $(TD $(LREF basicExceptionCtors) $(LREF emptyExceptionMsg) $(LREF ErrnoException) $(LREF RangePrimitive) )) )) Copyright: Copyright Andrei Alexandrescu 2008-, Jonathan M Davis 2011-. License: $(HTTP boost.org/LICENSE_1_0.txt, Boost License 1.0) Authors: $(HTTP erdani.org, Andrei Alexandrescu) and $(HTTP jmdavisprog.com, Jonathan M Davis) Source: $(PHOBOSSRC std/exception.d) +/ module std.exception; /// Synopis @system unittest { import core.stdc.stdlib : malloc, free; import std.algorithm.comparison : equal; import std.algorithm.iteration : map, splitter; import std.algorithm.searching : endsWith; import std.conv : ConvException, to; import std.range : front, retro; // use enforce like assert int a = 3; enforce(a > 2, "a needs to be higher than 2."); // enforce can throw a custom exception enforce!ConvException(a > 2, "a needs to be higher than 2."); // enforce will return it's input enum size = 42; auto memory = enforce(malloc(size), "malloc failed")[0 .. size]; scope(exit) free(memory.ptr); // collectException can be used to test for exceptions Exception e = collectException("abc".to!int); assert(e.file.endsWith("conv.d")); // and just for the exception message string msg = collectExceptionMsg("abc".to!int); assert(msg == "Unexpected 'a' when converting from type string to type int"); // assertThrown can be used to assert that an exception is thrown assertThrown!ConvException("abc".to!int); // ifThrown can be used to provide a default value if an exception is thrown assert("x".to!int().ifThrown(0) == 0); // handle is a more advanced version of ifThrown for ranges auto r = "12,1337z32,54".splitter(',').map!(a => to!int(a)); auto h = r.handle!(ConvException, RangePrimitive.front, (e, r) => 0); assert(h.equal([12, 0, 54])); assertThrown!ConvException(h.retro.equal([54, 0, 12])); // basicExceptionCtors avoids the boilerplate when creating custom exceptions static class MeaCulpa : Exception { mixin basicExceptionCtors; } e = collectException((){throw new MeaCulpa("diagnostic message");}()); assert(e.msg == "diagnostic message"); assert(e.file == __FILE__); assert(e.line == __LINE__ - 3); // assumeWontThrow can be used to cast throwing code into `nothrow` void exceptionFreeCode() nothrow { // auto-decoding only throws if an invalid UTF char is given assumeWontThrow("abc".front); } // assumeUnique can be used to cast mutable instance to an `immutable` one // use with care char[] str = " mutable".dup; str[0 .. 2] = "im"; immutable res = assumeUnique(str); assert(res == "immutable"); } import std.range.primitives; import std.traits; /++ Asserts that the given expression does $(I 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 `Throwable`s will escape. Params: T = The `Throwable` to test for. expression = The expression to test. 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. file = The file where the error occurred. Defaults to `__FILE__`. line = The line where the error occurred. Defaults to `__LINE__`. Throws: `AssertError` if the given `Throwable` is thrown. Returns: the result of `expression`. +/ auto assertNotThrown(T : Throwable = Exception, E) (lazy E expression, string msg = null, string file = __FILE__, size_t line = __LINE__) { import core.exception : AssertError; try { return expression(); } catch (T t) { immutable message = msg.length == 0 ? t.msg : msg; immutable tail = message.length == 0 ? "." : ": " ~ message; throw new AssertError("assertNotThrown failed: " ~ T.stringof ~ " was thrown" ~ tail, file, line, t); } } /// @system unittest { import core.exception : AssertError; import std.string; assertNotThrown!StringException(enforce!StringException(true, "Error!")); //Exception is the default. assertNotThrown(enforce!StringException(true, "Error!")); assert(collectExceptionMsg!AssertError(assertNotThrown!StringException( enforce!StringException(false, "Error!"))) == `assertNotThrown failed: StringException was thrown: Error!`); } @system unittest { import core.exception : AssertError; import std.string; assert(collectExceptionMsg!AssertError(assertNotThrown!StringException( enforce!StringException(false, ""), "Error!")) == `assertNotThrown failed: StringException was thrown: Error!`); assert(collectExceptionMsg!AssertError(assertNotThrown!StringException( enforce!StringException(false, ""))) == `assertNotThrown failed: StringException was thrown.`); assert(collectExceptionMsg!AssertError(assertNotThrown!StringException( enforce!StringException(false, ""), "")) == `assertNotThrown failed: StringException was thrown.`); } @system unittest { import core.exception : AssertError; static noreturn throwEx(Throwable t) { throw t; } bool nothrowEx() { return true; } try { assert(assertNotThrown!Exception(nothrowEx())); } catch (AssertError) assert(0); try { assert(assertNotThrown!Exception(nothrowEx(), "It's a message")); } catch (AssertError) assert(0); try { assert(assertNotThrown!AssertError(nothrowEx())); } catch (AssertError) assert(0); try { assert(assertNotThrown!AssertError(nothrowEx(), "It's a message")); } catch (AssertError) assert(0); { bool thrown = false; try { assertNotThrown!Exception( throwEx(new Exception("It's an Exception"))); } catch (AssertError) thrown = true; assert(thrown); } { bool thrown = false; try { assertNotThrown!Exception( throwEx(new Exception("It's an Exception")), "It's a message"); } catch (AssertError) thrown = true; assert(thrown); } { bool thrown = false; try { assertNotThrown!AssertError( throwEx(new AssertError("It's an AssertError", __FILE__, __LINE__))); } catch (AssertError) thrown = true; assert(thrown); } { bool thrown = false; try { assertNotThrown!AssertError( throwEx(new AssertError("It's an AssertError", __FILE__, __LINE__)), "It's a message"); } catch (AssertError) thrown = true; assert(thrown); } } /++ Asserts that the given expression throws the given type of `Throwable`. The `Throwable` is caught and does not escape assertThrown. However, any other `Throwable`s $(I will) escape, and if no `Throwable` of the given type is thrown, then an `AssertError` is thrown. Params: T = The `Throwable` to test for. expression = The expression to test. msg = Optional message to output on test failure. file = The file where the error occurred. Defaults to `__FILE__`. line = The line where the error occurred. Defaults to `__LINE__`. Throws: `AssertError` if the given `Throwable` is not thrown. +/ void assertThrown(T : Throwable = Exception, E) (lazy E expression, string msg = null, string file = __FILE__, size_t line = __LINE__) { import core.exception : AssertError; try expression(); catch (T) return; static if (!is(immutable E == immutable noreturn)) throw new AssertError("assertThrown failed: No " ~ T.stringof ~ " was thrown" ~ (msg.length == 0 ? "." : ": ") ~ msg, file, line); } /// @system unittest { import core.exception : AssertError; import std.string; assertThrown!StringException(enforce!StringException(false, "Error!")); //Exception is the default. assertThrown(enforce!StringException(false, "Error!")); assert(collectExceptionMsg!AssertError(assertThrown!StringException( enforce!StringException(true, "Error!"))) == `assertThrown failed: No StringException was thrown.`); } @system unittest { import core.exception : AssertError; static noreturn throwEx(Throwable t) { throw t; } void nothrowEx() { } try { assertThrown!Exception(throwEx(new Exception("It's an Exception"))); } catch (AssertError) assert(0); try { assertThrown!Exception(throwEx(new Exception("It's an Exception")), "It's a message"); } catch (AssertError) assert(0); try { assertThrown!AssertError(throwEx(new AssertError("It's an AssertError", __FILE__, __LINE__))); } catch (AssertError) assert(0); try { assertThrown!AssertError(throwEx(new AssertError("It's an AssertError", __FILE__, __LINE__)), "It's a message"); } catch (AssertError) assert(0); { bool thrown = false; try assertThrown!Exception(nothrowEx()); catch (AssertError) thrown = true; assert(thrown); } { bool thrown = false; try assertThrown!Exception(nothrowEx(), "It's a message"); catch (AssertError) thrown = true; assert(thrown); } { bool thrown = false; try assertThrown!AssertError(nothrowEx()); catch (AssertError) thrown = true; assert(thrown); } { bool thrown = false; try assertThrown!AssertError(nothrowEx(), "It's a message"); catch (AssertError) thrown = true; assert(thrown); } } /++ Enforces that the given value is true. If the given value is false, an exception is thrown. The $(UL $(LI `msg` - error message as a `string`) $(LI `dg` - custom delegate that return a string and is only called if an exception occurred) $(LI `ex` - custom exception to be thrown. It is `lazy` and is only created if an exception occurred) ) Params: value = The value to test. E = Exception type to throw if the value evaluates to false. msg = The error message to put in the exception if it is thrown. dg = The delegate to be called if the value evaluates to false. ex = The exception to throw if the value evaluates to false. file = The source file of the caller. line = The line number of the caller. Returns: `value`, if `cast(bool) value` is true. Otherwise, depending on the chosen overload, `new Exception(msg)`, `dg()` or `ex` is thrown. $(PANEL $(NOTE `enforce` is used to throw exceptions and is therefore intended to aid in error handling. It is $(I not) intended for verifying the logic of your program - that is what `assert` is for.) Do not use `enforce` inside of contracts (i.e. inside of `in` and `out` blocks and `invariant`s), because contracts are compiled out when compiling with $(I -release). ) If a delegate is passed, the safety and purity of this function are inferred from `Dg`'s safety and purity. +/ template enforce(E : Throwable = Exception) if (is(typeof(new E("", string.init, size_t.init)) : Throwable) || is(typeof(new E(string.init, size_t.init)) : Throwable)) { /// T enforce(T)(T value, lazy const(char)[] msg = null, string file = __FILE__, size_t line = __LINE__) if (is(typeof({ if (!value) {} }))) { if (!value) bailOut!E(file, line, msg); return value; } } /// ditto 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) dg(); return value; } /// ditto T enforce(T)(T value, lazy Throwable ex) { if (!value) throw ex(); return value; } /// @system unittest { import core.stdc.stdlib : malloc, free; import std.conv : ConvException, to; // use enforce like assert int a = 3; enforce(a > 2, "a needs to be higher than 2."); // enforce can throw a custom exception enforce!ConvException(a > 2, "a needs to be higher than 2."); // enforce will return it's input enum size = 42; auto memory = enforce(malloc(size), "malloc failed")[0 .. size]; scope(exit) free(memory.ptr); } /// @safe unittest { assertNotThrown(enforce(true, new Exception("this should not be thrown"))); assertThrown(enforce(false, new Exception("this should be thrown"))); } /// @safe unittest { assert(enforce(123) == 123); try { enforce(false, "error"); assert(false); } catch (Exception e)