- D Cookbook
- Adam D. Ruppe
- 572字
- 2021-07-16 11:50:44
Using a custom exception type
D uses exceptions to handle errors, just like many other programming languages. In D, exceptions are always implemented as classes that derive from the class Throwable
, and they are differentiated by their type. So, it is best to generate a new exception subclass for different types of errors your code can generate. This way, users of your code will get the most information and control out of your exceptions.
How to do it…
Let's use a custom exception type by using the following steps:
- Declare a class that inherits from
Exception
. - Make a constructor that takes, minimally, two parameters:
string file
andsize_t line
, with default values of__FILE__
and__LINE__
, respectively. - Have the constructor forward the arguments to the constructor of
Exception
. - Use your exception.
The following is the code:
class MyException : Exception { this(string message, string file = __FILE__, size_t line = __LINE__, Throwable next = null) { super(message, file, line, next); } } void main() { import std.stdio; try throw new MyException("message here"); catch(MyException e) writeln("caught ", e); }
How it works…
D uses exceptions to handle errors. All throwable objects inherit from either Exception
, for recoverable events, or Error
for unrecoverable errors, which generally ought not be caught. The common base class is Throwable
.
Typically, a custom exception inherits from Exception
, then declares, minimally, a constructor that forwards the functionality to super()
. You may also store additional information specific to your use case.
The constructor of Exception
(here, called with super()
) takes four arguments: a string message, a filename, a line number, and optionally, a reference to another exception. The message, filename, and line number are used to construct a message for the user, which is printed to the console if the exception is not caught.
You don't have to specify the file and line number at the throw site; any default argument of __FILE__
or __LINE__
is automatically expanded at the function's call site. This is useful to make the error message more useful by showing exactly where the exception came from.
The fourth parameter, Throwable next
, is used if an exception handler throws an exception. It references the exception that was being handled when this one was generated.
There's more…
You should check error codes when using the C functions and turn them into exceptions. If it sets errno
for error details, the std.exception
module has a subclass called ErrnoException
that is perfect for the following code:
import core.sys.posix.unistd; // for the low-level Posix functions import core.sys.posix.fnctl // for more low-level Posix functions import std.exception; // for ErrnoException auto fd = open("myfile.txt", O_RDONLY); // open() returns -1 if it was unable to open the file, // and sets errno with error details. Check for that failure. if(fd == -1) throw new ErrnoException("Couldn't open myfile.txt"); // close the file automatically at the end of the scope scope(exit) close(fd); /* read the file here */
See also
Scope guards, discussed in Chapter 5, Resource Management, are convenient for use with exceptions. They let you put clean-up or recovery code near the creation point in an exception-safe way. In the preceding example, you used a scope guard to ensure the file is properly closed when the function returns, even if an exception is thrown.
- 高效微控制器C語言編程
- 自己動手實現Lua:虛擬機、編譯器和標準庫
- 軟件測試項目實戰之性能測試篇
- Java設計模式及實踐
- 大學計算機基礎(第2版)(微課版)
- Drupal 8 Module Development
- 大學計算機基礎實驗指導
- Visual Studio 2015高級編程(第6版)
- 基于SpringBoot實現:Java分布式中間件開發入門與實戰
- Learning JavaScript Data Structures and Algorithms(Second Edition)
- 零基礎學HTML+CSS第2版
- 大學計算機基礎實訓教程
- Drupal 8 Development:Beginner's Guide(Second Edition)
- Java Web開發教程:基于Struts2+Hibernate+Spring
- Java核心編程