Skip to content

Conversation

@gmgunter
Copy link
Contributor

The PR adds several interrelated types for error-handling.

  • The ErrorCode class implements type erasure for a range of error code enumeration types, allowing for interoperability between various domain-specific and third-party error codes that the library may need to support.

    Unlike std::error_code, ErrorCode uses a variant/visitor idiom rather than dynamic polymorphism to implement type erasure. This makes it more intrusive to extend - you need to modify the class definition in order to support additional error codes. However, it allows ErrorCode to be constructed on the device and safely passed between host and device code. In addition, there's significantly less boilerplate code to maintain for each specific error code enumeration type.

  • The Error class pairs an error code with information about the source location where the error occurred (filename and line number).

  • Expected<T> is a wrapper that may contain an object of the template type T or an Error. It provides an alternative to traditional error handling mechanisms (such as exceptions and error codes) when used as a return type for operations which may fail. On success, the returned object contains the expected result. In case of failure, it instead contains an object that describes the error encountered.

    Compared to the use of exceptions, the Expected approach

    • can be used in device code and can be safely and easily propagated across thread boundaries
    • allows for inexpensive local handling of the "bad path" when an operation fails to return the expected value
    • improves error visibility in code review by making the possibility of error explicit in a function's return type

    Compared to error codes, Expected objects

    • do not monopolize the return channel
    • are not easily ignored (if the user wants to retrieve the contained value)

The ErrorCode class implements type erasure for a range of error code
enumeration types, allowing for interoperability between various
domain-specific and third-party error codes that the library may need to
support.

Unlike std::error_code, ErrorCode uses a variant/visitor idiom rather
than dynamic polymorphism to implement type erasure. This makes it more
intrusive to extend - you need to modify the class definition in order
to support additional error codes. However, it allows ErrorCode to be
constructed on the device and safely passed between host and device
code. In addition, there's significantly less boilerplate code to
maintain for each specific error code enumeration type.

This commit also adds two specific error code enumeration types -
DomainError and OutOfRange - as examples and for testing.
The Error class pairs an error code with information about the source
location where the error occurred (filename and line number). It is
implicitly constructible from an ErrorCode or any supported error code
enumeration type. By default, the source location info is populated
based on the call site where the Error object was constructed.

This implementation relies on std::experimental::source_location (from
<experimental/source_location>), which is supported in gcc >= 7 and
clang >= 9, to transparently capture source code location info. This
class is standardized in C++20 as std::source_location.
The Expected template class is a wrapper that may contain an object of
the template type T or an error. It is intended to be used as a return
type for operations which may fail. On success, the returned object
contains the expected result. In case of failure, it instead contains an
object that describes the error encountered.

The expected/unexpected idiom provides a useful alternative to
traditional error handling mechanisms such as exceptions and error
codes.

Compared to the use of exceptions, the Expected approach

- can be used in device code and can be safely and easily propagated
across thread boundaries
- allows for inexpensive local handling of the "bad path" when an
operation fails to return the expected value
- improves error visibility in code review by making the possibility of
error explicit in a function's return type

Compared to error codes, Expected objects

- do not monopolize the return channel
- are not easily ignored (if the user wants to retrieve the contained
value)
@gmgunter gmgunter requested review from aivazis and r-burns December 31, 2020 07:13
@gmgunter gmgunter changed the title Error v2 Add error handling utils (v2) Dec 31, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant