这里只针对用户异常 Exceptions,系统异常 Errors 通常是致命错误,不应该 被捕获。
异常的一个常见情况是验证可能无效的用户输入。一旦抛出异常,堆栈将被展开直到匹配到一个异常处理。
try
{
    readText("dummyFile");
}
catch (FileException e)
{
    // ...
}
可以有多个 catch 捕获块和一个 无论是否发生异常都会执行的 finally 语句。异常被 throw 关键字抛出。
try
{
    throw new StringException("You shall not pass.");
}
catch (FileException e)
{
    // ...
}
catch (StringException e)
{
    // ...
}
finally
{
    // ...
}
记住, scope guard 作用域保护 通常是比 try-finally 更好的方案。
可以很容易地继承 Exception 创建自定义异常。
class UserNotFoundException : Exception
{
    this(string msg, string file = __FILE__, size_t line = __LINE__) {
        super(msg, file, line);
    }
}
throw new UserNotFoundException("D-Man is on vacation");
nothrow 进入安全世界D 编译器可以确认哪些函数不会导致灾难性的副作用。这些函数可以被 nothrow 关键字注释,D 编译器将在静态检查中禁止在 nothrow 中抛出异常。
bool lessThan(int a, int b) nothrow
{
    writeln("unsafe world"); // 输出是可以抛出异常的,所以这里不能用 nothrow
    return a < b;
}
请注意,编译器可以自动判断判断模板代码的属性。
避免 assert 断言 是重要的,即将引入用户控制的 contract programming 与 assert 一样会在 release 发布模式下删除。
std.exception 提供了便捷的 
enforce,可以像 assert 一样使用,但是抛出 Exception 而不是一个 AssertError。
import std.exception : enforce;
float magic = 1_000_000_000;
enforce(magic + 42 - magic == 42, "Floating-point math is fun");
// 抛出一个自定义的异常
enforce!StringException('a' != 'A', "Case-sensitive algorithm");
在 std.exception 中还有很多功能,比如当异常可能不是致命的时候,可以选择使用 collect:
import std.exception : collectException;
auto e = collectException(aDangerousOperation());
if (e)
    writeln("The dangerous operation failed with ", e);
要测试是否抛出异常,请使用 assertThrown。