https://issues.dlang.org/show_bug.cgi?id=15219

          Issue ID: 15219
           Summary: Allow Throwable.msg to be calculated lazily
           Product: D
           Version: D2
          Hardware: All
                OS: All
            Status: NEW
          Severity: enhancement
          Priority: P4
         Component: druntime
          Assignee: nob...@puremagic.com
          Reporter: thecybersha...@gmail.com

In many cases, an exception's .msg property is not trivial to compose. At the
very least, it often involves GC allocations to format the exception string.
Sometimes it involves OS API calls, e.g. when the error is caused by a failed
I/O operation, in which case the appropriate OS error string is queried. For
parsing code, an exception message will often contain the line/column, which
also can have an additional cost to calculate or keep track of.

Since exceptions are usually caught and handled higher in the application, the
error message is never seen by the user, and all the effort to calculate it
goes to waste.

Currently, it is not possible to create an exception object whose .msg is
calculated lazily. There is the virtual toString method, inherited from Object,
however this method returns the exception formatted together with the stack
trace, and is unsuitable for overriding.

We can remedy this while mostly preserving backwards-compatibility with the
following steps:

1. Change the field "string msg" to "private string _msg".
2. Provide a virtual getter property "msg", which can be overridden to
calculate the exception message lazily.
3. For backwards compatibility, also provide a setter property "msg", which
sets the private _msg field.

Moving forward, since std.exception.enforce already takes its .msg parameter
lazily, it can be changed to subclass the respective exception type, override
the "msg" property, and return the "msg" argument passed to enforce. This
should give us a performance gain for free.

Possible backwards-compatibility problems can result due to changing
Throwable.msg to a property: code that takes the address of .msg, or code that
relies that accessing .msg is a O(1) or @nogc operation, will be affected, but
I think this is within the bounds of acceptable breakage.

--

Reply via email to