Skip to content
This repository was archived by the owner on Sep 2, 2025. It is now read-only.

Commit d63a427

Browse files
author
Dekel Barzilay
committed
- Changed error-handler to return only error message
- Original errors are now available via a secure Symbol - Bumped version to 4.8.0
1 parent 31bb004 commit d63a427

File tree

6 files changed

+77
-53
lines changed

6 files changed

+77
-53
lines changed

README.md

Lines changed: 24 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -786,7 +786,30 @@ Run the example with `node app` and go to
786786
You should see an empty array. That's because you don't have any Todos yet, but
787787
you now have full CRUD for your new todos service!
788788
789-
## Migrating
789+
## DB migrations
790+
791+
[Knex Migration CLI](http://knexjs.org/#Migrations) can be used to manage DB migrations
792+
and to [seed](http://knexjs.org/#Seeds) a table with mock data.
793+
794+
## Error handling
795+
796+
As of version 4.8.0, `feathers-objection` only throws [Feathers Errors](https://docs.feathersjs.com/api/errors.html)
797+
with the message.
798+
On the server, the original error can be retrieved through a secure symbol via `error[require('feathers-objection').ERROR]`.
799+
800+
```js
801+
const { ERROR } = require('feathers-objection');
802+
803+
try {
804+
await objectionService.doSomething();
805+
} catch (error) {
806+
// error is a FeathersError with just the message
807+
// Safely retrieve the original error
808+
const originalError = error[ERROR];
809+
}
810+
```
811+
812+
## Migrating to `feathers-objection` v2
790813
791814
`feathers-objection` 2.0.0 comes with important security and usability updates.
792815

package-lock.json

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
{
22
"name": "feathers-objection",
33
"description": "A service plugin for ObjectionJS an ORM based on KnexJS",
4-
"version": "4.7.0",
4+
"version": "4.8.0",
55
"homepage": "https://github.com/feathersjs-ecosystem/feathers-objection",
66
"keywords": [
77
"feathers",

src/error-handler.js

Lines changed: 32 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,9 @@
11
import errors from '@feathersjs/errors';
22

3-
export default function errorHandler (error) {
4-
error = error.nativeError || error;
3+
const ERROR = Symbol('feathers-knex/error');
54

5+
export default function errorHandler (error) {
6+
const { message } = error.nativeError || error;
67
let feathersError = error;
78

89
if (error.code === 'SQLITE_ERROR') {
@@ -12,114 +13,102 @@ export default function errorHandler (error) {
1213
case 18:
1314
case 19:
1415
case 20:
15-
feathersError = new errors.BadRequest(error);
16+
feathersError = new errors.BadRequest(message);
1617
break;
1718
case 2:
18-
feathersError = new errors.Unavailable(error);
19+
feathersError = new errors.Unavailable(message);
1920
break;
2021
case 3:
2122
case 23:
22-
feathersError = new errors.Forbidden(error);
23+
feathersError = new errors.Forbidden(message);
2324
break;
2425
case 12:
25-
feathersError = new errors.NotFound(error);
26+
feathersError = new errors.NotFound(message);
2627
break;
2728
default:
28-
feathersError = new errors.GeneralError(error);
29+
feathersError = new errors.GeneralError(message);
2930
break;
3031
}
31-
32-
throw feathersError;
33-
}
34-
35-
// Objection validation error
36-
if (error.statusCode) {
32+
} else if (error.statusCode) { // Objection validation error
3733
switch (error.statusCode) {
3834
case 400:
39-
feathersError = new errors.BadRequest(error);
35+
feathersError = new errors.BadRequest(message);
4036
break;
4137

4238
case 401:
43-
feathersError = new errors.NotAuthenticated(error);
39+
feathersError = new errors.NotAuthenticated(message);
4440
break;
4541

4642
case 402:
47-
feathersError = new errors.PaymentError(error);
43+
feathersError = new errors.PaymentError(message);
4844
break;
4945

5046
case 403:
51-
feathersError = new errors.Forbidden(error);
47+
feathersError = new errors.Forbidden(message);
5248
break;
5349

5450
case 404:
55-
feathersError = new errors.NotFound(error);
51+
feathersError = new errors.NotFound(message);
5652
break;
5753

5854
case 405:
59-
feathersError = new errors.MethodNotAllowed(error);
55+
feathersError = new errors.MethodNotAllowed(message);
6056
break;
6157

6258
case 406:
63-
feathersError = new errors.NotAcceptable(error);
59+
feathersError = new errors.NotAcceptable(message);
6460
break;
6561

6662
case 408:
67-
feathersError = new errors.Timeout(error);
63+
feathersError = new errors.Timeout(message);
6864
break;
6965

7066
case 409:
71-
feathersError = new errors.Conflict(error);
67+
feathersError = new errors.Conflict(message);
7268
break;
7369

7470
case 422:
75-
feathersError = new errors.Unprocessable(error);
71+
feathersError = new errors.Unprocessable(message);
7672
break;
7773

7874
case 501:
79-
feathersError = new errors.NotImplemented(error);
75+
feathersError = new errors.NotImplemented(message);
8076
break;
8177

8278
case 503:
83-
feathersError = new errors.Unavailable(error);
79+
feathersError = new errors.Unavailable(message);
8480
break;
8581

8682
case 500:
8783
default:
88-
feathersError = new errors.GeneralError(error);
89-
}
90-
91-
if (error.data) {
92-
feathersError.data = error.data;
84+
feathersError = new errors.GeneralError(message);
9385
}
94-
95-
throw feathersError;
96-
}
97-
98-
// Postgres error code
99-
// TODO
100-
// Properly detect postgres error
101-
if (typeof error.code === 'string') {
86+
} else if (typeof error.code === 'string') { // Postgres error code - TODO: Properly detect postgres error
10287
const pgerror = error.code.substring(0, 2);
10388

10489
switch (pgerror) {
10590
case '28':
10691
case '42':
107-
feathersError = new errors.Forbidden(error);
92+
feathersError = new errors.Forbidden(message);
10893
break;
10994

11095
case '20':
11196
case '21':
11297
case '22':
11398
case '23':
114-
feathersError = new errors.BadRequest(error);
99+
feathersError = new errors.BadRequest(message);
115100
break;
116101

117102
default:
118-
feathersError = new errors.GeneralError(error);
103+
feathersError = new errors.GeneralError(message);
119104
}
120-
121-
throw feathersError;
105+
} else if (!(error instanceof errors.FeathersError)) {
106+
feathersError = new errors.GeneralError(message);
122107
}
123108

109+
feathersError[ERROR] = error;
110+
124111
throw feathersError;
125112
}
113+
114+
errorHandler.ERROR = ERROR;

src/index.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -667,3 +667,4 @@ export default function init (options) {
667667
}
668668

669669
init.Service = Service;
670+
init.ERROR = errorHandler.ERROR;

test/index.test.js

Lines changed: 18 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ import feathers from '@feathersjs/feathers';
66
import knex from 'knex';
77
import adapterTests from '@feathersjs/adapter-tests';
88
import errors from '@feathersjs/errors';
9-
import service from '../src';
9+
import service, { ERROR } from '../src';
1010
import errorHandler from '../src/error-handler';
1111
import People from './people';
1212
import PeopleCustomid from './people-customid';
@@ -316,7 +316,19 @@ describe('Feathers Objection Service', () => {
316316
it('no error code', () => {
317317
const error = new Error('Unknown Error');
318318
expect(errorHandler.bind(null, error)).to.throw('Unknown Error');
319-
expect(errorHandler.bind(null, error)).to.not.throw(errors.GeneralError);
319+
expect(errorHandler.bind(null, error)).to.throw(errors.GeneralError);
320+
});
321+
322+
it('Get original error', () => {
323+
const error = new Error();
324+
error.code = 'SQLITE_ERROR';
325+
error.errno = 999;
326+
327+
try {
328+
errorHandler(error);
329+
} catch (err) {
330+
expect(err[ERROR]).to.deep.equal(error);
331+
}
320332
});
321333

322334
describe('SQLite', () => {
@@ -816,7 +828,6 @@ describe('Feathers Objection Service', () => {
816828
})
817829
.catch(error => {
818830
expect(error.code).to.equal(400);
819-
expect(error.data).to.deep.equal({});
820831
});
821832
});
822833
});
@@ -1201,7 +1212,7 @@ describe('Feathers Objection Service', () => {
12011212
throw new Error('Should never get here');
12021213
}).catch(function (error) {
12031214
expect(error).to.be.ok;
1204-
expect(error instanceof errors.BadRequest).to.be.ok;
1215+
expect(error instanceof errors.GeneralError).to.be.ok;
12051216
expect(error.message).to.equal('select `companies`.* from `companies` where CAST(`companies`.`jsonObject`#>>\'{numberField}\' AS text) = 1.5 - SQLITE_ERROR: unrecognized token: "#"');
12061217
});
12071218
});
@@ -1211,7 +1222,7 @@ describe('Feathers Objection Service', () => {
12111222
throw new Error('Should never get here');
12121223
}).catch(function (error) {
12131224
expect(error).to.be.ok;
1214-
expect(error instanceof errors.BadRequest).to.be.ok;
1225+
expect(error instanceof errors.GeneralError).to.be.ok;
12151226
expect(error.message).to.equal('select `companies`.* from `companies` where CAST(`companies`.`jsonObject`#>>\'{numberField}\' AS text) > 1.5 - SQLITE_ERROR: unrecognized token: "#"');
12161227
});
12171228
});
@@ -1221,7 +1232,7 @@ describe('Feathers Objection Service', () => {
12211232
throw new Error('Should never get here');
12221233
}).catch(function (error) {
12231234
expect(error).to.be.ok;
1224-
expect(error instanceof errors.BadRequest).to.be.ok;
1235+
expect(error instanceof errors.GeneralError).to.be.ok;
12251236
expect(error.message).to.equal('select `companies`.* from `companies` where CAST(`companies`.`jsonObject`#>>\'{objectField,object}\' AS text) = \'string in jsonObject.objectField.object\' - SQLITE_ERROR: unrecognized token: "#"');
12261237
});
12271238
});
@@ -1237,7 +1248,7 @@ describe('Feathers Objection Service', () => {
12371248
throw new Error('Should never get here');
12381249
}).catch(function (error) {
12391250
expect(error).to.be.ok;
1240-
expect(error instanceof errors.BadRequest).to.be.ok;
1251+
expect(error instanceof errors.GeneralError).to.be.ok;
12411252
expect(error.message).to.equal('select `companies`.* from `companies` where CAST(`companies`.`jsonArray`#>>\'{0,objectField,object}\' AS text) = \'I\'\'m string in jsonArray[0].objectField.object\' - SQLITE_ERROR: unrecognized token: "#"');
12421253
});
12431254
});

0 commit comments

Comments
 (0)