randolf.ca  1.00
Randolf's C++ classes
randolf::rex::rex Class Reference

Randolf's exceptions class, that takes errors from POSIX and OpenSSL functions and throws logically-named C++ exceptions. More...

+ Inheritance diagram for randolf::rex::rex:
+ Collaboration diagram for randolf::rex::rex:

Public Types

enum  REX_FLAGS : int {
  REX_DEFAULT = 0 ,
  REX_FIND_ERRNO = 1 ,
  REX_TLS = 2 ,
  REX_ALT_EAGAIN = 4096 ,
  REX_ALT_ENOTSUP = 8192
}
 Optional flags used with the static mk_exception() method to specify. More...
 

Public Member Functions

 rex ()
 Default constructor. More...
 
 rex (const char *m, long n=0, const int flags=REX_FLAGS::REX_DEFAULT)
 Construct exception with an ASCIIZ string. More...
 
 rex (const std::string &m, long n=0, const int flags=REX_FLAGS::REX_DEFAULT)
 Construct exception with an std::string object. More...
 
const long err_no () const noexcept
 Find out what the errno (or OpenSSL's ERR_get_error() number) was that caused this exception to be thrown. More...
 
const char * what () const noexcept
 Find out what the reason (usually the error code, e.g., EAGAIN) was for this exception to be thrown. More...
 

Static Public Member Functions

static void mk_exception (const std::string msg="", long rex_errno=0, const int flags=rex::REX_FLAGS::REX_DEFAULT)
 Arbitrarily throw an exception based on the error number. More...
 

Detailed Description

Randolf's exceptions class, that takes errors from POSIX and OpenSSL functions and throws logically-named C++ exceptions.

Every error that can be returned by a POSIX function (e.g., socket functions) is available as a subclass of the xALL exception, which is a subclass of rex, and which in turn is ultimately a subclass of std::exception.

Note
Exception names that begin with xALL_ are subclassed by other exceptions so that developers can capture specific groups of exceptions for easier error handling.

A minimal amount of hierarchy is included in this design so that developers can more conveniently capture groups of exceptions with a single catch statement. For example, since all errors beginning with xEAI_ are also a subclass of rex::xALL_EAI a single catch statement will capture all of them (the what() method can still be presented to the user so they may more easily differentiate the specific error).

Any errors that are added in the future (or were overlooked) belong in a special exception called rex::xUNKNOWN (note that there's no letter "E" prefixing this name so as to avoid any possible future conflict with a hypothetical
EUNKNOWN error ever being added to the POSIX standard.

Compilation dependencies
In your source code, the following include line is needed:
#include <randolf/rex>

When compiling, the crypto library is needed (for TLS/OpenSSL error handling, whether or not you actually use it; perhaps in the distant future I can look into the possibility of improving this source code header so the TLS/OpenSSL handling portions are conditionally included when compiling with the crypto library).

g++ -std=c++20 -x c++ rex -lcrypto
Background
This was originally built for the rsocket class, but I've moved it out into a separate C++ header file because it's useful for generating exceptions from other classes and projects too. So, now it's a general-purpose class that can be used independently (without any reliance on my other projects).
Conventions
All xTLS_ exceptions represent OpenSSL library errors prefixed with SSL_ERROR_, and all references to SSL are replaced by TLS so as to be in accordance with the fact that SSL was deprecated many years ago (TLS replaces SSL due to security weaknesses that were discovered with SSL) prior to the creation of this rex class.

Every TLS-related/SSL-related exception is documented to indicate which SSL_ERROR_ it represents, in an effort to make it easier (and clearer) which SSL_ERROR_ is being represented. (For the text representation of OpenSSL's error codes, we still present them just as the library does, using the SSL_ERROR_ prefix, so that users can more easily make sense of them and find helpful information if research them on the internet or ask others for help who are expecting these well-known/more-recognizable error names.)

Member Enumeration Documentation

◆ REX_FLAGS

Optional flags used with the static mk_exception() method to specify.

See also
randolf::rex::rex::mk_exception(const std::string, long, const int)
Enumerator
REX_DEFAULT 

The REX_DEFAULT flag isn't necessary, but it's included here for completeness as it accomodates programming styles that prefer to emphasize when defaults are being relied upon.

REX_FIND_ERRNO 

This will override whatever error number was provided to the constructor by querying errno or [for TLS errors] querying OpenSSL's ERR_peek_err function for the error code.

REX_TLS 

Indicate that the error code is from the OpenSSL library (some of which are in conflict with general/POSIX error codes, which is why this flag is necessary), and is not a general/POSIX error code.

REX_ALT_EAGAIN 

Throw xEAGAIN instead of xEWOULDBLOCK, if either the EAGAIN error code or the EWOULDBLOCK error code is encountered.

Note
Sometimes this is needed by mk_exception so that it constructs from the correct exception class because some Operating Systems use the same error code number for both of the respective errors as noted.

This is a workaround used primarily by the static mk_exception method so that the intended exception is thrown regardless of whether the error code numbers are properly differentiated.

REX_ALT_ENOTSUP 

Throw xENOTSUP instead of xEOPNOTSUPP, if either the ENOTSUP error code or the EOPNOTSUPP error code is encountered.

Note
Sometimes this is needed by mk_exception so that it constructs from the correct exception class because some Operating Systems use the same error code number for both of the respective errors as noted.

This is a workaround used primarily by the static mk_exception method so that the intended exception is thrown regardless of whether the error code numbers are properly differentiated.

Constructor & Destructor Documentation

◆ rex() [1/3]

randolf::rex::rex::rex ( )

Default constructor.

Note
This is to keep clang++ from generating hundreds of useless errors.
See also
mk_exception(std::string, long, int)

◆ rex() [2/3]

randolf::rex::rex::rex ( const char *  m,
long  n = 0,
const int  flags = REX_FLAGS::REX_DEFAULT 
)
inlineexplicit

Construct exception with an ASCIIZ string.

Note
When throwing an exception, it's not necessary to know the error number, which means that new types of errors can be introduced (although we really want to avoid deviating from the standard Linux API as much as possible).
See also
mk_exception(std::string, long, int)
Parameters
mError code as a pointer to an ASCIIZ string
nResult of the errno() function goes here (if known)
flagsFlags

◆ rex() [3/3]

randolf::rex::rex::rex ( const std::string &  m,
long  n = 0,
const int  flags = REX_FLAGS::REX_DEFAULT 
)
inlineexplicit

Construct exception with an std::string object.

Note
When throwing an exception, it's not necessary to know the error number, which means that new types of errors can be introduced (although we really want to avoid deviating from the standard Linux API as much as possible).
See also
mk_exception(std::string, long, int)
Parameters
mError code as an std::string
nResult of the errno() function goes here (if known)
flagsFlags

Member Function Documentation

◆ err_no()

const long randolf::rex::rex::err_no ( ) const
inlinenoexcept

Find out what the errno (or OpenSSL's ERR_get_error() number) was that caused this exception to be thrown.

Returns
Original errno() value

◆ mk_exception()

static void randolf::rex::rex::mk_exception ( const std::string  msg = "",
long  rex_errno = 0,
const int  flags = rex::REX_FLAGS::REX_DEFAULT 
)
static

Arbitrarily throw an exception based on the error number.

This is useful for developers who may need (or want) to throw a specific exception to ease error handling for circumstances that warrant throwing a particular exception that otherwise normally wouldn't be thrown (0 will also cause xUNKNOWN to be thrown).

If the error message text isn't known, then passing in an empty std::string will trigger the relevant error message to be generated automatically).

Note
The exception xTLS_ZERO_RETURN represents OpenSSL's error code 6, which is an actual error, unlike 0, which indicates that an error didn't occur.
Exceptions
rexhas many subclasses, all of which may be caught individually, or under one of the rex exceptions groups, such as xALL
See also
REX_FLAGS
Parameters
msgCustom error message (replaces default message if defined)
rex_errnoError number (N/A if REX_FIND_ERRNO is specified)
Ultimately, an error code of 0 has no effect and will result in no exception being thrown
flagsFlags that influence how exceptions are thrown

◆ what()

const char* randolf::rex::rex::what ( ) const
inlinenoexcept

Find out what the reason (usually the error code, e.g., EAGAIN) was for this exception to be thrown.

Returns
Error code text as a pointer to an ASCIIZ string

The documentation for this class was generated from the following file: