Skip to content

Instantly share code, notes, and snippets.

@patrickmmartin
Forked from anonymous/ERROR_TAXONOMIES.md
Last active December 12, 2016 17:03
Show Gist options
  • Save patrickmmartin/3969f2e5be7e90cc3901b922007c94c7 to your computer and use it in GitHub Desktop.
Save patrickmmartin/3969f2e5be7e90cc3901b922007c94c7 to your computer and use it in GitHub Desktop.
error taxonomies

Error Taxonomies

Some notes on the way people create taxonomies of errors.

Overview of basic approaches

bool return status

TODO(PMM)

Implementation

function value
out parameter

int return codes

TODO(PMM)

Implementation

function value
out parameter

Exceptions

TODO(PMM)

as pointed out in Crowl2015

The exception mechanism induces a large variance in the cost of a function call. This variance could cause problems on systems with hard real-time constraints.

This is often raised, but is this more a primary concern for library authors, and the significance of this concern will depend upon the application?

Complex Error structures

TODO(PMM)

Implementation

function value
out parameter

Strings (const or non-const)

TODO(PMM)

Implementation

function value
out parameter

Prior Papers

from [MartinKuhl2015]

  • only one type, essentially (equivalent to all types ;-) ?)
  • a program state is reached, whose salient environment "ORACLE is down" is unique
  • a program state is reached whose category is unique but whose environment is variable "table or view %s not found"

from [Crowl2015]

  • The system implementation failed, e.g. out of memory.
  • Something passed to the function failed, e.g. an exception thrown from a callback.
  • The function detected an inappropriate environment, e.g. null pointer parameter.
  • Data structure bounds prevent completion, e.g. pushing a full queue.
  • The disappointment is expected, e.g. popping an empty queue.

from [Kuhl2016]

  1. A function is unsuccessful because it is called out of contract. When a function is called out of contract the result is undefined behavior and there is no way to recover.
  2. The operation a function promises to perform is not always successful, e.g., because the outcome depends on values passed to the function and/or the state of the system. The unsuccessful outcomes are, however, part of the function's abstraction and can be determined when designing the interface without considering implementation details. This kind of failures is called semantic failures below. Semantic failures are best dealt locally using a status indication provided by the function.
  3. A function may encounter disappointing outcomes from operations it uses internally and which are not part of the abstraction. The details of the operation are outside the immediate control of the caller. This kind of failures is called system failures below. System failures are in this sense rather unrelated to the function's actual operation. System errors are best dealt with using exceptions.

from [LongshawWoodsNNNN]

Abstract is:

As systems become more complex it is increasingly difficult to anticipate and handle error conditions in a system.
The developers of the system must ensure that errors do not cause problems for the users of the system.
To do so, they should Keep Exceptions Exceptional, Hide Technical Details from Users and encapsulate the system in a Big Outer Try Block.
The administrators must be informed when an error occurs and must be given sufficient information about what happened, where it happened and why it happened.
If a system has Split Domain and Technical Errors and its components only Log Unexpected Errors then the level of error information can stay manageable.
If distributed systems Log at Distribution Boundaries then the overall error information in the system can be reduced and the consequences of individual errors can be tied together using a Unique Error Identifier.

Prior Art

Where some systems have defined exceptions and they were enthuisastically used.

c++

Anarchy could reign supreme ("throw -99", anyone?) but in the standard deployment we get throws() Yuck and a two category exception model: logic_error and runtime_error

Note that quite legally a completely evil or deranged author could throw only their class instances, sailing past all standard exception handlers.

Brief Hierarchy

exception
   logic_error
      domain_error
      invalid_argument
      length_error
      out_of_range
   runtime_error
      range_error
      overflow_error 
      underflow_error 

from http://stdcxx.apache.org/doc/stdlibug/18-2.html

Delphi

Singly rooted object hierarchy - all by reference - unified with OS SEH, so you can handle Access Violation or Floating Point Exception (That's SIGSEGV).

Exception types are declared just like other classes. In fact, it is possible to use an instance of any class as an exception, but it > is recommended that exceptions be derived from the SysUtils.Exception class defined in SysUtils.

Brief Hierarchy

type Exception = class(TObject);
EMathError = class(Exception);
EInvalidOp = class(EMathError);
EZeroDivide = class(EMathError);
EOverflow = class(EMathError);
EUnderflow = class(EMathError);

Java

Singly rooted object hierarchy - all by value (which is really a reference (JAVA!)) Checked exceptions NullPointerException SO POPULAR IT GOT ITS OWN TLA - "NPE" a.k.a. "the Dreaded NPE"

Brief Hierarchy

Java Throwable hierarchy

[MartinKuhl2015] https://accu.org/index.php/journals/2184
[Crowl2015] http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2015/p0157r0.html
[Kuhl2016] private communication
[LongshawWoodsNNNN] http://www.blueskyline.com/ErrorPatterns/ErrorPatternsPaper.pdf

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment