/** The exception module defines all system-level exceptions and provides a mechanism to alter system-level error handling. Copyright: Copyright Sean Kelly 2005 - 2013. License: $(HTTP www.boost.org/LICENSE_1_0.txt, Boost License 1.0). Authors: Sean Kelly and $(HTTP jmdavisprog.com, Jonathan M Davis) Source: $(DRUNTIMESRC core/_exception.d) */module core.exception; // Compiler lowers final switch default case to this (which is a runtime error)void __switch_errorT()(string file = __FILE__, size_t line = __LINE__) @trusted{ // Consider making this a compile time check. version (D_Exceptions) throw staticError!SwitchError("No appropriate switch clause found", file, line, null); else assert(0, "No appropriate switch clause found");} /* * Make sure template __switch_errorT is always instantiated when building * druntime. This works around https://issues.dlang.org/show_bug.cgi?id=20802. * When druntime and phobos are compiled with -release, the instance for * __switch_errorT is not needed. An application compiled with -release * could need the instance for __switch_errorT, but the compiler would * not generate code for it, because it assumes, that it was already * generated for druntime. Always including the instance in a compiled * druntime allows to use an application without -release with druntime * with -release. */private alias dummy__switch_errorT = __switch_errorT!(); /** * Thrown on a range error. */class RangeError : Error{ this( string file = __FILE__, size_t line = __LINE__, Throwable next = null ) @nogc nothrow pure @safe { super( "Range violation", file, line, next ); } protected this( string msg, string file, size_t line, Throwable next = null ) @nogc nothrow pure @safe { super( msg, file, line, next ); }} unittest{ { auto re = new RangeError(); assert(re.file == __FILE__); assert(re.line == __LINE__ - 2); assert(re.next is null); assert(re.msg == "Range violation"); } { auto re = new RangeError("hello", 42, new Exception("It's an Exception!")); assert(re.file == "hello"); assert(re.line == 42); assert(re.next !is null); assert(re.msg == "Range violation"); }} /** * Thrown when an out of bounds array index is accessed. */class ArrayIndexError : RangeError{ /// Index into array const size_t index; /// Length of indexed array const size_t length; // Buffer to avoid GC allocations private immutable char[100] msgBuf = '\0'; this(size_t index, size_t length, string file = __FILE__, size_t line = __LINE__, Throwable next = null) @nogc nothrow pure @safe { this.index = index; this.length = length; // Constructing the message is a bit clumsy: // It's essentially `printf("index [%zu] is out of bounds for array of length [%zu]", index, length)`, // but even `snprintf` isn't `pure`. // Also string concatenation isn't `@nogc`, and casting to/from immutable isn't `@safe` import core.internal.string : unsignedToTempString; char[msgBuf.length] buf = void; char[20] tmpBuf = void; char[] sink = buf[]; sink.rangeMsgPut("index ["); sink.rangeMsgPut(unsignedToTempString!10(index, tmpBuf)); sink.rangeMsgPut("] is out of bounds for array of length "); sink.rangeMsgPut(unsignedToTempString!10(length, tmpBuf)); this.msgBuf = buf; super(msgBuf[0..$-sink.length], file, line, next); }} @safe pure unittest{ assert(new ArrayIndexError(900, 700).msg == "index [900] is out of bounds for array of length 700"); // Ensure msg buffer doesn't overflow on large numbers assert(new ArrayIndexError(size_t.max, size_t.max-1).msg);} unittest{ try { _d_arraybounds_indexp("test", 400, 9, 3); assert(0, "no ArrayIndexError thrown"); } catch (ArrayIndexError re) { assert(re.file == "test"); assert(re.line == 400); assert(re.index == 9); assert(re.length == 3); }} /** * Thrown when an out of bounds array slice is created */class ArraySliceError : RangeError{ /// Lower/upper bound passed to slice: `array[lower .. upper]` const size_t lower, upper; /// Length of sliced array const size_t length; private immutable char[120] msgBuf = '\0'; this(size_t lower, size_t upper, size_t length, string file = __FILE__, size_t line = __LINE__, Throwable next = null) @nogc nothrow pure @safe { this.lower = lower; this.upper = upper; this.length = length; // Constructing the message is a bit clumsy for the same reasons as ArrayIndexError import core.internal.string : unsignedToTempString; char[msgBuf.length] buf = void; char[20] tmpBuf = void; char[] sink = buf; sink.rangeMsgPut("slice ["); sink.rangeMsgPut(unsignedToTempString!10(lower, tmpBuf)); sink.rangeMsgPut(" .. "); sink.rangeMsgPut(unsignedToTempString!10(upper, tmpBuf)); sink.rangeMsgPut("] "); if (lower > upper) { sink.rangeMsgPut("has a larger lower index than upper index"); } else { sink.rangeMsgPut("extends past source array of length "); sink.rangeMsgPut(unsignedToTempString!10(length, tmpBuf)); } this.msgBuf = buf; super(msgBuf[0..$-sink.length], file, line, next); }} @safe pure unittest{ assert(new ArraySliceError(40, 80, 20).msg == "slice [40 .. 80] extends past source array of length 20"); assert(new ArraySliceError(90, 70, 20).msg == "slice [90 .. 70] has a larger lower index than upper index"); // Ensure msg buffer doesn't overflow on large numbers assert(new ArraySliceError(size_t.max, size_t.max, size_t.max-1).msg);} unittest{ try { _d_arraybounds_slicep("test", 400, 1, 7, 3); assert(0, "no ArraySliceError thrown"); } catch (ArraySliceError re) { assert(re.file == "test"); assert(re.line == 400); assert(re.lower == 1); assert(re.upper == 7); assert(re.length == 3); }} /// Mini `std.range.primitives: put` for constructor of ArraySliceError / ArrayIndexErrorprivate void rangeMsgPut(ref char[] r, scope const(char)[] e) @nogc nothrow pure @safe{ assert(r.length >= e.length); // don't throw ArraySliceError inside ArrayIndexError ctor r[0 .. e.length] = e[]; r = r[e.length .. $];} /** * Thrown on an assert error. */class AssertError : Error{ @safe pure nothrow @nogc this( string file, size_t line ) { this(cast(Throwable)null, file, line); } @safe pure nothrow @nogc this( Throwable next, string file = __FILE__, size_t line = __LINE__ ) { this( "Assertion failure", file, line, next); } @safe pure nothrow @nogc this( string msg, string file = __FILE__, size_t line = __LINE__, Throwable next = null ) { super( msg, file, line, next ); }} unittest{ { auto ae = new AssertError("hello", 42); assert(ae.file == "hello"); assert(ae.line == 42); assert(ae.next is null); assert(ae.msg == "Assertion failure"); } { auto ae = new AssertError(new Exception("It's an Exception!")); assert(ae.file == __FILE__); assert(ae.line == __LINE__ - 2); assert(ae.next !is null); assert(ae.msg == "Assertion failure"); } { auto ae = new AssertError(new Exception("It's an Exception!"), "hello", 42); assert(ae.file == "hello"); assert(ae.line == 42); assert(ae.next !is null); assert(ae.msg == "Assertion failure"); } { auto ae = new AssertError("msg"); assert(ae.file == __FILE__); assert(ae.line == __LINE__ - 2); assert(ae.next is null); assert(ae.msg == "msg"); } { auto ae = new AssertError("msg", "hello", 42); assert(ae.file == "hello"); assert(ae.line == 42); assert(ae.next is null); assert(ae.msg == "msg"); } { auto ae = new AssertError("msg", "hello", 42, new Exception("It's an Exception!")); assert(ae.file == "hello"); assert(ae.line == 42); assert(ae.next !is null); assert(ae.msg == "msg"); }} /** * When an unmapped pointer is accessed this may be thrown via a signal handler. */class InvalidPointerError : Error{ @safe pure nothrow @nogc this(string file, size_t line) { this(file, line, cast(Throwable)null); } @safe pure nothrow @nogc this(string file = __FILE__, size_t line = __LINE__, Throwable next = null) { this("Invalid pointer access", file, line, next); } @safe pure nothrow @nogc this(string msg, string file = __FILE__, size_t line = __LINE__, Throwable next = null) { super(msg, file, line, next); }} /** * Thrown when a null dereference may occur. * * Depends upon null dereference check, or a signal handler to throw. */class NullPointerError : InvalidPointerError{ @safe pure nothrow @nogc this(string file, size_t line) { this(file, line, cast(Throwable)null); } @safe pure nothrow @nogc this(string file = __FILE__, size_t line = __LINE__, Throwable next = null) { this("Null pointer dereference", file, line, next); } @safe pure nothrow @nogc this(string msg, string file = __FILE__, size_t line = __LINE__, Throwable next = null) { super(msg, file, line, next); }} /** * Thrown on finalize error. */class FinalizeError : Error{ TypeInfo info; this( TypeInfo ci, Throwable next, string file = __FILE__, size_t line = __LINE__ ) @safe pure nothrow @nogc { this(ci, file, line, next); } this( TypeInfo ci, string file = __FILE__, size_t line = __LINE__, Throwable next = null ) @safe pure nothrow @nogc { super( "Finalization error", file, line, next ); info = ci; } override string toString() const @safe { return "An exception was thrown while finalizing an instance of " ~ info.toString(); }} unittest{ ClassInfo info = new ClassInfo; info.name = "testInfo"; { auto fe = new FinalizeError(info); assert(fe.file == __FILE__); assert(fe.line == __LINE__ - 2); assert(fe.next is null); assert(fe.msg == "Finalization error"); assert(fe.info == info); } { auto fe = new FinalizeError(info, new Exception("It's an Exception!")); assert(fe.file == __FILE__); assert(fe.line == __LINE__ - 2); assert(fe.next !is null); assert(fe.msg == "Finalization error"); assert(fe.info == info); } { auto fe = new FinalizeError(info, "hello", 42); assert(fe.file == "hello"); assert(fe.line == 42); assert(fe.next is null); assert(fe.msg == "Finalization error"); assert(fe.info == info); } { auto fe = new FinalizeError(info, "hello", 42, new Exception("It's an Exception!")); assert(fe.file == "hello"); assert(fe.line == 42); assert(fe.next !is null); assert(fe.msg == "Finalization error"); assert(fe.info == info); }} /** * Thrown on an out of memory error. */class OutOfMemoryError : Error{ this(string file = __FILE__, size_t line = __LINE__, Throwable next = null ) @safe pure nothrow @nogc { this(true, file, line, next); } this(bool trace, string file = __FILE__, size_t line = __LINE__, Throwable next = null ) @safe pure nothrow @nogc { super("Memory allocation failed", file, line, next); if (!trace) this.info = SuppressTraceInfo.instance; } override string toString() const @trusted { return msg.length ? (cast()this).superToString() : "Memory allocation failed"; } // kludge to call non-const super.toString private string superToString() @trusted { return super.toString(); }} unittest{ { auto oome = new OutOfMemoryError(); assert(oome.file == __FILE__); assert(oome.line == __LINE__ - 2); assert(oome.next is null); assert(oome.msg == "Memory allocation failed"); assert(oome.toString.length); } { auto oome = new OutOfMemoryError("hello", 42, new Exception("It's an Exception!")); assert(oome.file == "hello"); assert(oome.line == 42); assert(oome.next !is null); assert(oome.msg == "Memory allocation failed"); }} /** * Thrown on an invalid memory operation. * * An invalid memory operation error occurs in circumstances when the garbage * collector has detected an operation it cannot reliably handle. The default * D GC is not re-entrant, so this can happen due to allocations done from * within finalizers called during a garbage collection cycle. */class InvalidMemoryOperationError : Error{ this(string file = __FILE__, size_t line = __LINE__, Throwable next = null ) @safe pure nothrow @nogc { super( "Invalid memory operation", file, line, next ); } override string toString() const @trusted { return msg.length ? (cast()this).superToString() : "Invalid memory operation"; } // kludge to call non-const super.toString private string superToString() @trusted { return super.toString(); }} unittest{ { auto oome = new InvalidMemoryOperationError(); assert(oome.file == __FILE__); assert(oome.line == __LINE__ - 2); assert(oome.next is null); assert(oome.msg == "Invalid memory operation"); assert(oome.toString.length); } { auto oome = new InvalidMemoryOperationError("hello", 42, new Exception("It's an Exception!")); assert(oome.file == "hello"); assert(oome.line == 42); assert(oome.next !is null); assert(oome.msg == "Invalid memory operation"); }} /*** Thrown on a configuration error.*/class ForkError : Error{ this( string file = __FILE__, size_t line = __LINE__, Throwable next = null ) @nogc nothrow pure @safe { super( "fork() failed", file, line, next ); }} /** * Thrown on a switch error. */Lines 1–500 of 1004. Load more
/** The exception module defines all system-level exceptions and provides a mechanism to alter system-level error handling. Copyright: Copyright Sean Kelly 2005 - 2013. License: $(HTTP www.boost.org/LICENSE_1_0.txt, Boost License 1.0). Authors: Sean Kelly and $(HTTP jmdavisprog.com, Jonathan M Davis) Source: $(DRUNTIMESRC core/_exception.d) */ module core.exception; // Compiler lowers final switch default case to this (which is a runtime error) void __switch_errorT()(string file = __FILE__, size_t line = __LINE__) @trusted { // Consider making this a compile time check. version (D_Exceptions) throw staticError!SwitchError("No appropriate switch clause found", file, line, null); else assert(0, "No appropriate switch clause found"); } /* * Make sure template __switch_errorT is always instantiated when building * druntime. This works around https://issues.dlang.org/show_bug.cgi?id=20802. * When druntime and phobos are compiled with -release, the instance for * __switch_errorT is not needed. An application compiled with -release * could need the instance for __switch_errorT, but the compiler would * not generate code for it, because it assumes, that it was already * generated for druntime. Always including the instance in a compiled * druntime allows to use an application without -release with druntime * with -release. */ private alias dummy__switch_errorT = __switch_errorT!(); /** * Thrown on a range error. */ class RangeError : Error { this( string file = __FILE__, size_t line = __LINE__, Throwable next = null ) @nogc nothrow pure @safe { super( "Range violation", file, line, next ); } protected this( string msg, string file, size_t line, Throwable next = null ) @nogc nothrow pure @safe { super( msg, file, line, next ); } } unittest { { auto re = new RangeError(); assert(re.file == __FILE__); assert(re.line == __LINE__ - 2); assert(re.next is null); assert(re.msg == "Range violation"); } { auto re = new RangeError("hello", 42, new Exception("It's an Exception!")); assert(re.file == "hello"); assert(re.line == 42); assert(re.next !is null); assert(re.msg == "Range violation"); } } /** * Thrown when an out of bounds array index is accessed. */ class ArrayIndexError : RangeError { /// Index into array const size_t index; /// Length of indexed array const size_t length; // Buffer to avoid GC allocations private immutable char[100] msgBuf = '\0'; this(size_t index, size_t length, string file = __FILE__, size_t line = __LINE__, Throwable next = null) @nogc nothrow pure @safe { this.index = index; this.length = length; // Constructing the message is a bit clumsy: // It's essentially `printf("index [%zu] is out of bounds for array of length [%zu]", index, length)`, // but even `snprintf` isn't `pure`. // Also string concatenation isn't `@nogc`, and casting to/from immutable isn't `@safe` import core.internal.string : unsignedToTempString; char[msgBuf.length] buf = void; char[20] tmpBuf = void; char[] sink = buf[]; sink.rangeMsgPut("index ["); sink.rangeMsgPut(unsignedToTempString!10(index, tmpBuf)); sink.rangeMsgPut("] is out of bounds for array of length "); sink.rangeMsgPut(unsignedToTempString!10(length, tmpBuf)); this.msgBuf = buf; super(msgBuf[0..$-sink.length], file, line, next); } } @safe pure unittest { assert(new ArrayIndexError(900, 700).msg == "index [900] is out of bounds for array of length 700"); // Ensure msg buffer doesn't overflow on large numbers assert(new ArrayIndexError(size_t.max, size_t.max-1).msg); } unittest { try { _d_arraybounds_indexp("test", 400, 9, 3); assert(0, "no ArrayIndexError thrown"); } catch (ArrayIndexError re) { assert(re.file == "test"); assert(re.line == 400); assert(re.index == 9); assert(re.length == 3); } } /** * Thrown when an out of bounds array slice is created */ class ArraySliceError : RangeError { /// Lower/upper bound passed to slice: `array[lower .. upper]` const size_t lower, upper; /// Length of sliced array const size_t length; private immutable char[120] msgBuf = '\0'; this(size_t lower, size_t upper, size_t length, string file = __FILE__, size_t line = __LINE__, Throwable next = null) @nogc nothrow pure @safe { this.lower = lower; this.upper = upper; this.length = length; // Constructing the message is a bit clumsy for the same reasons as ArrayIndexError import core.internal.string : unsignedToTempString; char[msgBuf.length] buf = void; char[20] tmpBuf = void; char[] sink = buf; sink.rangeMsgPut("slice ["); sink.rangeMsgPut(unsignedToTempString!10(lower, tmpBuf)); sink.rangeMsgPut(" .. "); sink.rangeMsgPut(unsignedToTempString!10(upper, tmpBuf)); sink.rangeMsgPut("] "); if (lower > upper) { sink.rangeMsgPut("has a larger lower index than upper index"); } else { sink.rangeMsgPut("extends past source array of length "); sink.rangeMsgPut(unsignedToTempString!10(length, tmpBuf)); } this.msgBuf = buf; super(msgBuf[0..$-sink.length], file, line, next); } } @safe pure unittest { assert(new ArraySliceError(40, 80, 20).msg == "slice [40 .. 80] extends past source array of length 20"); assert(new ArraySliceError(90, 70, 20).msg == "slice [90 .. 70] has a larger lower index than upper index"); // Ensure msg buffer doesn't overflow on large numbers assert(new ArraySliceError(size_t.max, size_t.max, size_t.max-1).msg); } unittest { try { _d_arraybounds_slicep("test", 400, 1, 7, 3); assert(0, "no ArraySliceError thrown"); } catch (ArraySliceError re) { assert(re.file == "test"); assert(re.line == 400); assert(re.lower == 1); assert(re.upper == 7); assert(re.length == 3); } } /// Mini `std.range.primitives: put` for constructor of ArraySliceError / ArrayIndexError private void rangeMsgPut(ref char[] r, scope const(char)[] e) @nogc nothrow pure @safe { assert(r.length >= e.length); // don't throw ArraySliceError inside ArrayIndexError ctor r[0 .. e.length] = e[]; r = r[e.length .. $]; } /** * Thrown on an assert error. */ class AssertError : Error { @safe pure nothrow @nogc this( string file, size_t line ) { this(cast(Throwable)null, file, line); } @safe pure nothrow @nogc this( Throwable next, string file = __FILE__, size_t line = __LINE__ ) { this( "Assertion failure", file, line, next); } @safe pure nothrow @nogc this( string msg, string file = __FILE__, size_t line = __LINE__, Throwable next = null ) { super( msg, file, line, next ); } } unittest { { auto ae = new AssertError("hello", 42); assert(ae.file == "hello"); assert(ae.line == 42); assert(ae.next is null); assert(ae.msg == "Assertion failure"); } { auto ae = new AssertError(new Exception("It's an Exception!")); assert(ae.file == __FILE__); assert(ae.line == __LINE__ - 2); assert(ae.next !is null); assert(ae.msg == "Assertion failure"); } { auto ae = new AssertError(new Exception("It's an Exception!"), "hello", 42); assert(ae.file == "hello"); assert(ae.line == 42); assert(ae.next !is null); assert(ae.msg == "Assertion failure"); } { auto ae = new AssertError("msg"); assert(ae.file == __FILE__); assert(ae.line == __LINE__ - 2); assert(ae.next is null); assert(ae.msg == "msg"); } { auto ae = new AssertError("msg", "hello", 42); assert(ae.file == "hello"); assert(ae.line == 42); assert(ae.next is null); assert(ae.msg == "msg"); } { auto ae = new AssertError("msg", "hello", 42, new Exception("It's an Exception!")); assert(ae.file == "hello"); assert(ae.line == 42); assert(ae.next !is null); assert(ae.msg == "msg"); } } /** * When an unmapped pointer is accessed this may be thrown via a signal handler. */ class InvalidPointerError : Error { @safe pure nothrow @nogc this(string file, size_t line) { this(file, line, cast(Throwable)null); } @safe pure nothrow @nogc this(string file = __FILE__, size_t line = __LINE__, Throwable next = null) { this("Invalid pointer access", file, line, next); } @safe pure nothrow @nogc this(string msg, string file = __FILE__, size_t line = __LINE__, Throwable next = null) { super(msg, file, line, next); } } /** * Thrown when a null dereference may occur. * * Depends upon null dereference check, or a signal handler to throw. */ class NullPointerError : InvalidPointerError { @safe pure nothrow @nogc this(string file, size_t line) { this(file, line, cast(Throwable)null); } @safe pure nothrow @nogc this(string file = __FILE__, size_t line = __LINE__, Throwable next = null) { this("Null pointer dereference", file, line, next); } @safe pure nothrow @nogc this(string msg, string file = __FILE__, size_t line = __LINE__, Throwable next = null) { super(msg, file, line, next); } } /** * Thrown on finalize error. */ class FinalizeError : Error { TypeInfo info; this( TypeInfo ci, Throwable next, string file = __FILE__, size_t line = __LINE__ ) @safe pure nothrow @nogc { this(ci, file, line, next); } this( TypeInfo ci, string file = __FILE__, size_t line = __LINE__, Throwable next = null ) @safe pure nothrow @nogc { super( "Finalization error", file, line, next ); info = ci; } override string toString() const @safe { return "An exception was thrown while finalizing an instance of " ~ info.toString(); } } unittest { ClassInfo info = new ClassInfo; info.name = "testInfo"; { auto fe = new FinalizeError(info); assert(fe.file == __FILE__); assert(fe.line == __LINE__ - 2); assert(fe.next is null); assert(fe.msg == "Finalization error"); assert(fe.info == info); } { auto fe = new FinalizeError(info, new Exception("It's an Exception!")); assert(fe.file == __FILE__); assert(fe.line == __LINE__ - 2); assert(fe.next !is null); assert(fe.msg == "Finalization error"); assert(fe.info == info); } { auto fe = new FinalizeError(info, "hello", 42); assert(fe.file == "hello"); assert(fe.line == 42); assert(fe.next is null); assert(fe.msg == "Finalization error"); assert(fe.info == info); } { auto fe = new FinalizeError(info, "hello", 42, new Exception("It's an Exception!")); assert(fe.file == "hello"); assert(fe.line == 42); assert(fe.next !is null); assert(fe.msg == "Finalization error"); assert(fe.info == info); } } /** * Thrown on an out of memory error. */ class OutOfMemoryError : Error { this(string file = __FILE__, size_t line = __LINE__, Throwable next = null ) @safe pure nothrow @nogc { this(true, file, line, next); } this(bool trace, string file = __FILE__, size_t line = __LINE__, Throwable next = null ) @safe pure nothrow @nogc { super("Memory allocation failed", file, line, next); if (!trace) this.info = SuppressTraceInfo.instance; } override string toString() const @trusted { return msg.length ? (cast()this).superToString() : "Memory allocation failed"; } // kludge to call non-const super.toString private string superToString() @trusted { return super.toString(); } } unittest { { auto oome = new OutOfMemoryError(); assert(oome.file == __FILE__); assert(oome.line == __LINE__ - 2); assert(oome.next is null); assert(oome.msg == "Memory allocation failed"); assert(oome.toString.length); } { auto oome = new OutOfMemoryError("hello", 42, new Exception("It's an Exception!")); assert(oome.file == "hello"); assert(oome.line == 42); assert(oome.next !is null); assert(oome.msg == "Memory allocation failed"); } } /** * Thrown on an invalid memory operation. * * An invalid memory operation error occurs in circumstances when the garbage * collector has detected an operation it cannot reliably handle. The default * D GC is not re-entrant, so this can happen due to allocations done from * within finalizers called during a garbage collection cycle. */ class InvalidMemoryOperationError : Error { this(string file = __FILE__, size_t line = __LINE__, Throwable next = null ) @safe pure nothrow @nogc { super( "Invalid memory operation", file, line, next ); } override string toString() const @trusted { return msg.length ? (cast()this).superToString() : "Invalid memory operation"; } // kludge to call non-const super.toString private string superToString() @trusted { return super.toString(); } } unittest { { auto oome = new InvalidMemoryOperationError(); assert(oome.file == __FILE__); assert(oome.line == __LINE__ - 2); assert(oome.next is null); assert(oome.msg == "Invalid memory operation"); assert(oome.toString.length); } { auto oome = new InvalidMemoryOperationError("hello", 42, new Exception("It's an Exception!")); assert(oome.file == "hello"); assert(oome.line == 42); assert(oome.next !is null); assert(oome.msg == "Invalid memory operation"); } } /** * Thrown on a configuration error. */ class ForkError : Error { this( string file = __FILE__, size_t line = __LINE__, Throwable next = null ) @nogc nothrow pure @safe { super( "fork() failed", file, line, next ); } } /** * Thrown on a switch error. */