1 module ddbus.exception;
2 
3 import ddbus.c_lib;
4 
5 package T wrapErrors(T)(T delegate(DBusError* err) del, string file = __FILE__,
6     size_t line = __LINE__, Throwable next = null) {
7   DBusError error;
8   dbus_error_init(&error);
9   T ret = del(&error);
10   if (dbus_error_is_set(&error)) {
11     auto ex = new DBusException(&error, file, line, next);
12     dbus_error_free(&error);
13     throw ex;
14   }
15   return ret;
16 }
17 
18 /++
19   Thrown when a DBus error code was returned by libdbus.
20 +/
21 class DBusException : Exception {
22   private this(scope DBusError* err, string file = __FILE__,
23       size_t line = __LINE__, Throwable next = null) pure nothrow {
24     import std..string : fromStringz;
25 
26     super(err.message.fromStringz().idup, file, line, next);
27   }
28 }
29 
30 /++
31   Thrown when the signature of a message does not match the requested types or
32   when trying to get a value from a DBusAny object that does not match the type
33   of its actual value.
34 +/
35 class TypeMismatchException : Exception {
36   package this(int expectedType, int actualType, string file = __FILE__,
37       size_t line = __LINE__, Throwable next = null) pure nothrow @safe {
38     string message;
39 
40     // dfmt off
41     if (expectedType == 'v') {
42       message = "The type of value at the current position in the message is"
43         ~ " incompatible to the target variant type." ~ " Type code of the value: '"
44         ~ cast(char) actualType ~ '\'';
45     } else {
46       message = "The type of value at the current position in the message does"
47         ~ " not match the type of value to be read." ~ " Expected: '"
48         ~ cast(char) expectedType ~ "'," ~ " Got: '" ~ cast(char) actualType ~ '\'';
49     }
50     // dfmt on
51 
52     this(message, expectedType, actualType, file, line, next);
53   }
54 
55   this(string message, int expectedType, int actualType, string file = __FILE__,
56       size_t line = __LINE__, Throwable next = null) pure nothrow @safe {
57     _expectedType = expectedType;
58     _actualType = actualType;
59     super(message, file, line, next);
60   }
61 
62   int expectedType() @property pure const nothrow @safe @nogc {
63     return _expectedType;
64   }
65 
66   int actualType() @property pure const nothrow @safe @nogc {
67     return _actualType;
68   }
69 
70 private:
71   int _expectedType;
72   int _actualType;
73 }
74 
75 /++
76   Thrown during type conversion between DBus types and D types when a value is
77   encountered that can not be represented in the target type.
78 
79   This exception should not normally be thrown except when dealing with D types
80   that have a constrained value set, such as Enums.
81 +/
82 class InvalidValueException : Exception {
83   package this(Source)(Source value, string targetType, string file = __FILE__,
84       size_t line = __LINE__, Throwable next = null) {
85     import std.conv : to;
86 
87     static if (__traits(compiles, value.to!string)) {
88       string valueString = value.to!string;
89     } else {
90       string valueString = "(unprintable)";
91     }
92 
93     super("Value " ~ valueString ~ " cannot be represented in type " ~ targetType);
94   }
95 }