- 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.
- WildFly:New Features
- Advanced Machine Learning with Python
- 劍指Offer(專項突破版):數據結構與算法名企面試題精講
- PHP+MySQL+Dreamweaver動態網站開發實例教程
- Web程序設計(第二版)
- FLL+WRO樂高機器人競賽教程:機械、巡線與PID
- 零基礎學Python網絡爬蟲案例實戰全流程詳解(高級進階篇)
- Mastering Web Application Development with AngularJS
- Visual Studio Code 權威指南
- Scala Functional Programming Patterns
- 快樂編程:青少年思維訓練
- Android編程權威指南(第4版)
- 算法訓練營:海量圖解+競賽刷題(入門篇)
- Swift Essentials(Second Edition)
- 秒懂算法:用常識解讀數據結構與算法