Skip to content

Commit 8f6ceb2

Browse files
committed
add option fcmResolveUnhandledClientError
1 parent 148feae commit 8f6ceb2

File tree

3 files changed

+57
-16
lines changed

3 files changed

+57
-16
lines changed

spec/.eslintrc.json

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
{
2+
"env": {
3+
"jasmine": true
4+
},
5+
"globals": {
6+
"Parse": true
7+
},
8+
"rules": {
9+
"no-console": [0],
10+
"no-var": "error"
11+
}
12+
}

spec/FCM.spec.js

Lines changed: 35 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -2,20 +2,23 @@ import path from 'path';
22
import log from 'npmlog';
33
import FCM from '../src/FCM.js';
44
import { getApps, deleteApp } from 'firebase-admin/app';
5+
import Parse from 'parse/node.js';
56

6-
const testArgs = {
7-
firebaseServiceAccount: path.join(
8-
__dirname,
9-
'..',
10-
'spec',
11-
'support',
12-
'fakeServiceAccount.json',
13-
),
14-
};
7+
let testArgs;
158

169
describe('FCM', () => {
1710
beforeEach(async () => {
1811
getApps().forEach(app => deleteApp(app));
12+
13+
testArgs = {
14+
firebaseServiceAccount: path.join(
15+
__dirname,
16+
'..',
17+
'spec',
18+
'support',
19+
'fakeServiceAccount.json',
20+
),
21+
};
1922
});
2023

2124
it('can initialize', () => {
@@ -221,9 +224,29 @@ describe('FCM', () => {
221224
expect(spyError).toHaveBeenCalledWith('parse-server-push-adapter FCM', 'error sending push: testing error abort');
222225
});
223226

224-
it('can handle exceptions that are unhandled by the FCM client', async () => {
227+
it('rejects exceptions that are unhandled by FCM client', async () => {
228+
const spyInfo = spyOn(log, 'info').and.callFake(() => {});
229+
const spyError = spyOn(log, 'error').and.callFake(() => {});
230+
testArgs.fcmResolveUnhandledClientError = false;
231+
const fcm = new FCM(testArgs);
232+
spyOn(fcm.sender, 'sendEachForMulticast').and.callFake(() => {
233+
throw new Error('test error');
234+
});
235+
fcm.pushType = 'android';
236+
const data = { data: { alert: 'alert' } };
237+
const devices = [{ deviceToken: 'token' }];
238+
await expectAsync(fcm.send(data, devices)).toBeRejectedWith(new Parse.Error(Parse.Error.OTHER_CAUSE, 'Error: test error'));
239+
expect(fcm.sender.sendEachForMulticast).toHaveBeenCalled();
240+
expect(spyInfo).toHaveBeenCalledWith('parse-server-push-adapter FCM', 'sending push to 1 devices');
241+
expect(spyError).toHaveBeenCalledTimes(2);
242+
expect(spyError.calls.all()[0].args).toEqual(['parse-server-push-adapter FCM', 'error sending push: firebase client exception: Error: test error']);
243+
expect(spyError.calls.all()[1].args).toEqual(['parse-server-push-adapter FCM', 'error sending push: ParseError: -1 Error: test error']);
244+
});
245+
246+
it('resolves exceptions that are unhandled by FCM client', async () => {
225247
const spyInfo = spyOn(log, 'info').and.callFake(() => {});
226248
const spyError = spyOn(log, 'error').and.callFake(() => {});
249+
testArgs.fcmResolveUnhandledClientError = true;
227250
const fcm = new FCM(testArgs);
228251
spyOn(fcm.sender, 'sendEachForMulticast').and.callFake(() => {
229252
throw new Error('test error');
@@ -235,8 +258,8 @@ describe('FCM', () => {
235258
expect(fcm.sender.sendEachForMulticast).toHaveBeenCalled();
236259
expect(spyInfo).toHaveBeenCalledWith('parse-server-push-adapter FCM', 'sending push to 1 devices');
237260
expect(spyError).toHaveBeenCalledTimes(2);
238-
expect(spyError.calls.all()[0].args).toEqual(['parse-server-push-adapter FCM', 'error sending push: firebase client did not handle exception: Error: test error']);
239-
expect(spyError.calls.all()[1].args).toEqual(['parse-server-push-adapter FCM', 'error sending push: Error: test error']);
261+
expect(spyError.calls.all()[0].args).toEqual(['parse-server-push-adapter FCM', 'error sending push: firebase client exception: Error: test error']);
262+
expect(spyError.calls.all()[1].args).toEqual(['parse-server-push-adapter FCM', 'error sending push: ParseError: -1 Error: test error']);
240263
});
241264

242265
it('FCM request invalid push type', async () => {

src/FCM.js

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,9 @@ export default function FCM(args, pushType) {
2828
const fcmEnableLegacyHttpTransport = typeof args.fcmEnableLegacyHttpTransport === 'boolean'
2929
? args.fcmEnableLegacyHttpTransport
3030
: false;
31+
this.fcmResolveUnhandledClientError = typeof args.fcmResolveUnhandledClientError === 'boolean'
32+
? args.fcmResolveUnhandledClientError
33+
: false;
3134

3235
let app;
3336
if (getApps().length === 0) {
@@ -94,8 +97,8 @@ FCM.prototype.send = function (data, devices) {
9497
try {
9598
return this.sender.sendEachForMulticast(fcmPayloadData);
9699
} catch (err) {
97-
log.error(LOG_PREFIX, `error sending push: firebase client did not handle exception: ${err}`);
98-
return Promise.reject(err);
100+
log.error(LOG_PREFIX, `error sending push: firebase client exception: ${err}`);
101+
return Promise.reject(new Parse.Error(Parse.Error.OTHER_CAUSE, err));
99102
}
100103
};
101104

@@ -150,8 +153,11 @@ FCM.prototype.send = function (data, devices) {
150153

151154
const allPromises = Promise.all(
152155
slices.map((slice) => sendToDeviceSlice(slice, this.pushType)),
153-
).catch((err) => {
154-
log.error(LOG_PREFIX, `error sending push: ${err}`);
156+
).catch(e => {
157+
log.error(LOG_PREFIX, `error sending push: ${e}`);
158+
if (!this.fcmResolveUnhandledClientError && e instanceof Parse.Error && e.code === Parse.Error.OTHER_CAUSE) {
159+
return Promise.reject(e);
160+
}
155161
});
156162

157163
return allPromises;

0 commit comments

Comments
 (0)