Skip to content

Commit 8409de5

Browse files
authored
Merge pull request #160 from bryanburgers/error-class
Error class
2 parents f2f0a66 + d4c5823 commit 8409de5

13 files changed

+179
-11
lines changed

README.md

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -358,6 +358,28 @@ made (via `addMethod`, `addProperty`, and `addSignal`), `update` must be called
358358
to ensure that other DBus clients can see the changes that were made.
359359

360360

361+
### DBus.Error
362+
363+
A DBus-specific error
364+
365+
#### `new DBus.Error(name, message)`
366+
367+
* name `<string>` - A valid DBus Error name, according to the [specification][spec]
368+
* message `<string>` - A human readable message
369+
370+
Create a new error. The name must be a valid error name.
371+
372+
```
373+
throw new DBus.Error('com.example.Library.Error.BookExistsError', 'The book already exists');
374+
```
375+
376+
#### `dbusError.dbusName`
377+
378+
The DBus Error name of the error. When a DBus.Error is created, its message is
379+
set to the human-readable error message. The `dbusName` property is set to the
380+
name (according to the DBus Spec).
381+
382+
361383
## License
362384

363385
(The MIT License)
@@ -383,3 +405,4 @@ CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
383405
TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
384406
SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
385407

408+
[spec]: https://dbus.freedesktop.org/doc/dbus-specification.html

examples/service.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ iface1.addMethod('Dummy', {}, function(callback) {
1717
});
1818

1919
iface1.addMethod('MakeError', { out: DBus.Define(String) }, function(callback) {
20-
callback(new Error('nodejs.dbus.ExampleService.ErrorTest'));
20+
callback(new DBus.Error('nodejs.dbus.ExampleService.ErrorTest', 'Some error'));
2121
});
2222

2323
iface1.addMethod('Hello', { out: DBus.Define(String) }, function(callback) {

lib/dbus.js

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ var _dbus = require('../build/Release/dbus.node');
55
var Utils = require('./utils');
66
var Bus = require('./bus');
77
var Service = require('./service');
8+
var Error = require('./error');
89

910
var serviceMap = {};
1011

@@ -36,6 +37,7 @@ var DBus = module.exports = function(opts) {
3637

3738
DBus.Define = Utils.Define;
3839
DBus.Signature = Utils.Signature;
40+
DBus.Error = Error;
3941

4042
DBus.prototype.getBus = function(busName) {
4143
var self = this;
@@ -128,9 +130,14 @@ DBus.prototype._sendErrorMessageReply = function(message, name, msg) {
128130
_dbus.sendErrorMessageReply(message, name, msg);
129131
};
130132

131-
DBus.prototype.callMethod = function() {
133+
function createError(name, message) {
134+
return new DBus.Error(name, message);
135+
}
132136

133-
_dbus.callMethod.apply(this, Array.prototype.slice.call(arguments));
137+
DBus.prototype.callMethod = function() {
138+
var args = Array.prototype.slice.call(arguments);
139+
args.push(createError);
140+
_dbus.callMethod.apply(this, args);
134141
};
135142

136143
DBus.prototype.setMaxMessageSize = function(bus, size) {

lib/error.js

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
var util = require('util');
2+
3+
function DBusError(name, message) {
4+
Error.call(this, message);
5+
this.message = message;
6+
this.dbusName = name;
7+
8+
if (Error.captureStackTrace) {
9+
Error.captureStackTrace(this, 'DBusError');
10+
}
11+
else {
12+
Object.defineProperty(this, 'stack', { value: (new Error()).stack });
13+
}
14+
}
15+
16+
util.inherits(DBusError, Error);
17+
18+
DBusError.prototype.toString = function() {
19+
return 'DBusError: ' + this.message;
20+
}
21+
22+
module.exports = DBusError;

lib/interface.js

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -75,10 +75,6 @@ Interface.prototype.init = function(callback) {
7575
});
7676
};
7777
})(methodName, self.object['method'][methodName]['in'].join('') || '');
78-
self[methodName].timeout = -1;
79-
self[methodName].finish = null;
80-
self[methodName].error = null;
81-
8278
}
8379

8480
// Initializing signal handler

lib/service_interface.js

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -95,7 +95,8 @@ ServiceInterface.prototype.call = function(method, message, args) {
9595

9696
// Error handling
9797
if (value instanceof Error) {
98-
self.object.service.bus.dbus._sendErrorMessageReply(message, value.message);
98+
var name = value.dbusName || 'org.freedesktop.DBus.Error.Failed';
99+
self.object.service.bus.dbus._sendErrorMessageReply(message, name, value.message);
99100
return;
100101
}
101102

src/dbus.cc

Lines changed: 34 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -37,10 +37,38 @@ namespace NodeDBus {
3737

3838
Local<Value> err = Nan::Null();
3939
if (dbus_error_is_set(&error)) {
40-
err = Nan::Error(error.message);
40+
if (error.message != NULL) {
41+
Local<Value> createErrorParameters[] = {
42+
Nan::New(error.name).ToLocalChecked(),
43+
Nan::New(error.message).ToLocalChecked()
44+
};
45+
err = data->createError->Call(2, createErrorParameters);
46+
}
47+
else {
48+
Local<Value> createErrorParameters[] = {
49+
Nan::New(error.name).ToLocalChecked(),
50+
Nan::Undefined()
51+
};
52+
err = data->createError->Call(2, createErrorParameters);
53+
}
4154
dbus_error_free(&error);
4255
} else if (dbus_message_get_type(reply_message) == DBUS_MESSAGE_TYPE_ERROR) {
43-
err = Nan::Error(dbus_message_get_error_name(reply_message));
56+
dbus_set_error_from_message(&error, reply_message);
57+
if (error.message != NULL) {
58+
Local<Value> createErrorParameters[] = {
59+
Nan::New(error.name).ToLocalChecked(),
60+
Nan::New(error.message).ToLocalChecked()
61+
};
62+
err = data->createError->Call(2, createErrorParameters);
63+
}
64+
else {
65+
Local<Value> createErrorParameters[] = {
66+
Nan::New(error.name).ToLocalChecked(),
67+
Nan::Undefined()
68+
};
69+
err = data->createError->Call(2, createErrorParameters);
70+
}
71+
dbus_error_free(&error);
4472
}
4573

4674
// Decode message for arguments
@@ -129,6 +157,9 @@ namespace NodeDBus {
129157
if (!info[8]->IsFunction())
130158
return Nan::ThrowError("Require callback function");
131159

160+
if (!info[9]->IsFunction())
161+
return Nan::ThrowError("Require createError function");
162+
132163
int timeout = -1;
133164
if (info[6]->IsInt32())
134165
timeout = info[6]->Int32Value();
@@ -219,6 +250,7 @@ namespace NodeDBus {
219250
DBusAsyncData *data = new DBusAsyncData;
220251
data->pending = pending;
221252
data->callback = new Nan::Callback(info[8].As<Function>());
253+
data->createError = new Nan::Callback(info[9].As<Function>());
222254
if (!dbus_pending_call_set_notify(pending, method_callback, data, method_free)) {
223255
if (message != NULL)
224256
dbus_message_unref(message);

src/dbus.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,8 +20,10 @@ namespace NodeDBus {
2020
// Nan::Persistent<Function> callback;
2121
Nan::Callback *callback;
2222
DBusPendingCall *pending;
23+
Nan::Callback *createError;
2324

2425
~DBusAsyncData() {
26+
delete createError;
2527
delete callback;
2628
}
2729
} DBusAsyncData;

test/client-call-error.test.js

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
var withService = require('./with-service');
2+
var tap = require('tap');
3+
var DBus = require('../');
4+
5+
tap.plan(10);
6+
withService('service.js', function(err, done) {
7+
if (err) throw err;
8+
9+
var dbus = new DBus();
10+
var bus = dbus.getBus('session');
11+
12+
bus.getInterface('test.dbus.TestService', '/test/dbus/TestService', 'test.dbus.TestService.Interface1', function(err, iface) {
13+
iface.ThrowsError({ timeout: 1000 }, function(err, result) {
14+
tap.notSame(err, null);
15+
tap.same(result, null);
16+
tap.match(err.message, /from.*service/);
17+
tap.match(err.dbusName, 'org.freedesktop.DBus.Error.Failed');
18+
tap.type(err, DBus.Error);
19+
20+
iface.ThrowsCustomError({ timeout: 1000 }, function(err, result) {
21+
tap.notSame(err, null);
22+
tap.same(result, null);
23+
tap.match(err.message, /from.*service/);
24+
tap.match(err.dbusName, 'test.dbus.TestService.Error');
25+
tap.type(err, DBus.Error);
26+
done();
27+
bus.disconnect();
28+
});
29+
});
30+
});
31+
});

test/client-property-error.test.js

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
var withService = require('./with-service');
2+
var tap = require('tap');
3+
var DBus = require('../');
4+
5+
tap.plan(4);
6+
withService('service.js', function(err, done) {
7+
if (err) throw err;
8+
9+
var dbus = new DBus();
10+
var bus = dbus.getBus('session');
11+
12+
bus.getInterface('test.dbus.TestService', '/test/dbus/TestService', 'test.dbus.TestService.Interface1', function(err, iface) {
13+
iface.getProperty('ErrorProperty', function(err, value) {
14+
tap.notSame(err, null);
15+
tap.same(value, null);
16+
tap.match(err.message, /from.*service/);
17+
tap.type(err, DBus.Error);
18+
done();
19+
bus.disconnect();
20+
});
21+
});
22+
});

0 commit comments

Comments
 (0)