File indexing completed on 2024-04-28 16:59:49

0001 /*
0002     Design notes about errors.
0003 
0004     Errors can come (including but not limited to...) from these areas:
0005     - Arguments assembly
0006       - invalid construct, e.g. empty struct, dict with key but no value, dict with invalid key type,
0007         writing different (non-variant) types in different array elements
0008       - limit exceeded (message size, nesting depth etc)
0009       - invalid single data (e.g. null in string, too long string)
0010     - Arguments disassembly
0011       - malformed data (mostly manifesting as limit exceeded, since the format has little room for
0012         "grammar errors" - almost everything could theoretically be valid data)
0013       - invalid single data
0014       - trying to read something incompatible with reader state
0015     - Message assembly
0016       - required headers not present
0017     - Message disassembly
0018       - required headers not present (note: sender header in bus connections! not currently checked.)
0019     - I/O errors
0020       - could not open connection - any sub-codes?
0021       - disconnected
0022       - timeout??
0023       - (read a malformed message - connection should be closed)
0024       - discrepancy in number of file descriptors advertised and actually received - when this
0025         is implemented
0026     - artifacts of the implementation; not much - using a default-constructed PendingReply, anything else?
0027     - error codes from standardized DBus interfaces like the introspection thing; I think the convenience
0028       stuff should really be separate! Maybe separate namespace, in any case separate enum
0029 
0030     an error (if any) propagates in the following way, so you don't need to check at every step:
0031     Arguments::Writer -> Arguments -> Message -> PendingReply
0032 
0033 */
0034 
0035 #ifndef ERROR_H
0036 #define ERROR_H
0037 
0038 #include "types.h"
0039 
0040 #include <string>
0041 
0042 class DFERRY_EXPORT Error {
0043 public:
0044     enum Code : uint32 {
0045         // Error error ;)
0046         NoError = 0,
0047 
0048         // Arguments errors
0049         NotAttachedToArguments,
0050         InvalidSignature,
0051         ReplacementDataIsShorter,
0052         MalformedMessageData,
0053         ReadWrongType,
0054         NotPrimitiveType,
0055         InvalidType,
0056         InvalidString,
0057         InvalidObjectPath,
0058         SignatureTooLong,
0059         ExcessiveNesting,
0060         CannotEndArgumentsHere,
0061         ArgumentsTooLong,
0062 
0063         NotSingleCompleteTypeInVariant,
0064         EmptyVariant,
0065         CannotEndVariantHere,
0066 
0067         EmptyStruct,
0068         CannotEndStructHere,
0069 
0070         NotSingleCompleteTypeInArray,
0071         TypeMismatchInSubsequentArrayIteration,
0072         CannotEndArrayHere,
0073         CannotEndArrayOrDictHere,
0074         TooFewTypesInArrayOrDict,
0075         InvalidStateToRestartEmptyArray,
0076         InvalidKeyTypeInDict,
0077         GreaterTwoTypesInDict,
0078         ArrayOrDictTooLong,
0079         StateNotSkippable,
0080 
0081         MissingBeginDictEntry = 1019,
0082         MisplacedBeginDictEntry,
0083         MissingEndDictEntry,
0084         MisplacedEndDictEntry,
0085         // we have a lot of error codes at our disposal, so reserve some for easy classification
0086         // by range
0087         MaxArgumentsError = 1023,
0088         // end Arguments errors
0089 
0090         // Message  / PendingReply
0091         DetachedPendingReply,
0092         Timeout,
0093         MalformedReply, // Catch-all for failed reply validation - can't be corrected locally anyway.
0094                         // Since the reply isn't fully pre-validated for performance reasons,
0095                         // absence of this error is no guarantee of well-formedness.
0096 
0097         MessageType,        // ||| all of these may potentially mean missing for the type of message
0098         MessageSender,      // vvv or locally found to be invalid (invalid object path for example)
0099         MessageDestination,
0100         MessagePath,
0101         MessageInterface,
0102         MessageSignature,
0103         MessageMethod,
0104         MessageErrorName,
0105         MessageSerial,
0106         MessageReplySerial,
0107         MessageProtocolVersion,
0108 
0109 
0110         PeerNoSuchReceiver,
0111         PeerNoSuchPath,
0112         PeerNoSuchInterface,
0113         PeerNoSuchMethod,
0114 
0115         ArgumentTypeMismatch,
0116         PeerInvalidProperty,
0117         PeerNoSuchProperty,
0118         AccessDenied, // for now(?) only properties: writing to read-only / reading from write-only
0119         MaxMessageError = 2047,
0120         // end Message / PendingReply errors
0121 
0122         // Connection
0123         AuthenticationFailed,
0124         RemoteDisconnect,
0125         LocalDisconnect,
0126         SendingTooManyUnixFds, // The FD capacity varies by transport, so this error is only produced
0127                                // when trying to send a message with too many FDs. It is fine to pass
0128                                // around a message with lots of file descriptors locally.
0129         MaxConnectionError = 3071,
0130 
0131         // errors for other occasions go here
0132     };
0133 
0134     Error() : m_code(NoError) {}
0135     Error(Code code) : m_code(code) {}
0136     void setCode(Code code) { m_code = code; }
0137     Code code() const { return m_code; }
0138     bool isError() const { return m_code != NoError; }
0139     // no setter for message - it is just looked up from a static table according to error code
0140     std::string message() const;
0141 
0142 private:
0143     Code m_code;
0144 };
0145 
0146 #endif // ERROR_H