IException.h
// IException.h
//
// Author David Barrett-Lennard
// (C)opyright Cedanet Pty Ltd 2004
#pragma once
#ifndef Ceda_cxUtils_IException_H
#define Ceda_cxUtils_IException_H
#include "cxUtils.h"
namespace ceda
{
/* ################## Error Handling Issues / Results of discussions April 2007 ################3
The consensus on how to work with errors seems to be after much discussion:
- prefer error codes to exceptions when returning errors
- when some exceptions are already thrown by a function, perhaps ??? should prefer exceptions over error codes
because using error codes AND exceptions is in a way a more complicated contract (for example, see ApplyDeltas
it was already throwing CorruptLSSException and ApplyDeltaException, and was trying to decide whether it should
throw FileException or use an error code, and decided on exceptions for this exact reason.
- errors can chain (decorate one another)
- exceptions can't chain because they should be thrown by value and caught by reference (scott meyers book)
- IErrors AND IExceptions should have a GetKey function, which returns a unique key for that which is used to
look up a registry for providing internationalisation. The registry is as below, it stores a map from
(ErrorKey,Language) to WriteFunction.
- Registered WriteFunctions can downcast the IError ???? (/ IException) passed to them because they're written
for a specific kind of exception, they can then access it's state in order to produce statefull error
messages such as "File Error (fjdls.ced) file could not be opened"
- Todo: resolve the problem that IExceptions can't chain & IErrors can, yet we want to be able to register
internationalised write functions for both. Do we make the registry pass a void* to the write function,
and it knows to downcast to the appropriate type? Seems like it'd be safe.
// Prototype for error write functions, these can be written and registered to write errors
// the function will written will know the type of error that is passed and can therefore
// qicast to the specific type of error to get at its state (for example a windows 32 error
// code and filename would be stored in a FileError
$functor void WriteFunction(xostream& os, IError* error) const;
// register a WriteFunction functor to write an error for the error with ErrorKey key in
// the given language. Stored in a map from (ErrorKey,Language) to WriteFunction.
void RegisterErrorFunction(ErrorKey key, const Language* language, WriteFunction fn);
struct IError
{
virtual ErrorKey GetKey() const = 0;
virtual IError* GetInnerError() const = 0;
}
*/
class xostream;
///////////////////////////////////////////////////////////////////////////////////////////////////
// IException
// All ceda related exceptions implement this interface. Note that we avoid std::exception
// because it doesn't provide a reliable binary standard given that implementors of the STL are
// free to implement std::exception in any way they like.
struct cxUtils_API IException
{
// This was added so exceptions are thrown and caught correctly on ARMv7.
// See https://developer.android.com/ndk/guides/common-problems
virtual ~IException();
// Write a description of the exception to the given ostream
virtual void Write(xostream& os) const = 0;
};
} // namespace ceda
#endif // include guard