Skip to content

Commit 6cfb7fb

Browse files
committed
Cleaned up implementation and updated session error types
1 parent 21e59c9 commit 6cfb7fb

File tree

4 files changed

+55
-87
lines changed

4 files changed

+55
-87
lines changed

src/messaging/messaging.ts

Lines changed: 48 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -206,68 +206,69 @@ export class Messaging {
206206
MessagingClientErrorCode.INVALID_ARGUMENT, 'dryRun must be a boolean');
207207
}
208208

209-
// const http2SessionHandler = this.useLegacyTransport ? undefined : new Http2SessionHandler(`https://${FCM_SEND_HOST}`)
210-
const http2SessionHandler = this.useLegacyTransport ? undefined : new Http2SessionHandler(`https://localhost:3001`);
211-
209+
const http2SessionHandler = this.useLegacyTransport ? undefined : new Http2SessionHandler(`https://${FCM_SEND_HOST}`);
212210

213211
return this.getUrlPath()
214212
.then((urlPath) => {
215-
// Try listening for errors here?
216-
if (http2SessionHandler){
217-
let batchResponsePromise: Promise<PromiseSettledResult<SendResponse>[]>
213+
if (http2SessionHandler) {
214+
let batchResponsePromise: Promise<PromiseSettledResult<SendResponse>[]>;
218215
return new Promise((resolve: (result: PromiseSettledResult<SendResponse>[]) => void, reject) => {
216+
// Start session listeners
219217
http2SessionHandler.invoke().catch((error) => {
220-
console.log("ERROR TO BE PASSED TO USER:")
221-
console.log(error)
222-
reject({error, batchResponsePromise})
223-
})
224-
218+
error.pendingBatchResponse =
219+
batchResponsePromise ? batchResponsePromise.then(this.parseSendResponses) : undefined;
220+
reject(error);
221+
});
225222

223+
// Start making requests
226224
const requests: Promise<SendResponse>[] = copy.map(async (message) => {
227225
validateMessage(message);
228-
const request: { message: Message; validate_only?: boolean } = { message };
226+
const request: { message: Message; validate_only?: boolean; } = { message };
229227
if (dryRun) {
230228
request.validate_only = true;
231229
}
232230
return this.messagingRequestHandler.invokeHttp2RequestHandlerForSendResponse(
233-
FCM_SEND_HOST, urlPath, request, http2SessionHandler);
231+
FCM_SEND_HOST, urlPath, request, http2SessionHandler);
234232
});
235-
batchResponsePromise = Promise.allSettled(requests)
236-
batchResponsePromise.then(resolve).catch((error) => {
237-
reject({error, batchResponsePromise})
238-
})
239-
})
240-
}
241233

242-
//
243-
const requests: Promise<SendResponse>[] = copy.map(async (message) => {
244-
validateMessage(message);
245-
const request: { message: Message; validate_only?: boolean } = { message };
246-
if (dryRun) {
247-
request.validate_only = true;
248-
}
249-
return this.messagingRequestHandler.invokeHttpRequestHandlerForSendResponse(FCM_SEND_HOST, urlPath, request);
250-
});
251-
return Promise.allSettled(requests);
252-
//
253-
254-
})
255-
.then((results) => {
256-
const responses: SendResponse[] = [];
257-
results.forEach(result => {
258-
if (result.status === 'fulfilled') {
259-
responses.push(result.value);
260-
} else { // rejected
261-
responses.push({ success: false, error: result.reason })
262-
}
263-
})
264-
const successCount: number = responses.filter((resp) => resp.success).length;
265-
return {
266-
responses,
267-
successCount,
268-
failureCount: responses.length - successCount,
269-
};
234+
// Resolve once all requests have completed
235+
batchResponsePromise = Promise.allSettled(requests);
236+
batchResponsePromise.then(resolve);
237+
});
238+
} else {
239+
const requests: Promise<SendResponse>[] = copy.map(async (message) => {
240+
validateMessage(message);
241+
const request: { message: Message; validate_only?: boolean; } = { message };
242+
if (dryRun) {
243+
request.validate_only = true;
244+
}
245+
return this.messagingRequestHandler.invokeHttpRequestHandlerForSendResponse(
246+
FCM_SEND_HOST, urlPath, request);
247+
});
248+
return Promise.allSettled(requests);
249+
}
270250
})
251+
.then(this.parseSendResponses)
252+
.finally(() => {
253+
http2SessionHandler?.close();
254+
});
255+
}
256+
257+
private parseSendResponses(results: PromiseSettledResult<SendResponse>[]): BatchResponse {
258+
const responses: SendResponse[] = [];
259+
results.forEach(result => {
260+
if (result.status === 'fulfilled') {
261+
responses.push(result.value);
262+
} else { // rejected
263+
responses.push({ success: false, error: result.reason });
264+
}
265+
});
266+
const successCount: number = responses.filter((resp) => resp.success).length;
267+
return {
268+
responses,
269+
successCount,
270+
failureCount: responses.length - successCount,
271+
};
271272
}
272273

273274
/**

src/utils/api-request.ts

Lines changed: 6 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -847,19 +847,12 @@ class AsyncHttp2Call extends AsyncRequestCall {
847847
...this.options.headers
848848
});
849849

850-
// console.log("EMIT SESSION ERROR")
851-
// this.http2ConfigImpl.http2SessionHandler.session.emit('error', "MOCK_SESSION_ERROR")
852-
853850
req.on('response', (headers: IncomingHttp2Headers) => {
854851
this.handleHttp2Response(headers, req);
855-
856-
// console.log("EMIT SESSION ERROR")
857-
// this.http2ConfigImpl.http2SessionHandler.session.emit('error', "MOCK_ERROR")
858852
});
859853

860854
// Handle errors
861855
req.on('error', (err: any) => {
862-
console.log("GOT REQUEST ERROR")
863856
if (req.aborted) {
864857
return;
865858
}
@@ -1061,6 +1054,7 @@ class Http2RequestConfigImpl extends BaseRequestConfigImpl implements Http2Reque
10611054

10621055
public buildRequestOptions(): https.RequestOptions {
10631056
const parsed = this.buildUrl();
1057+
// TODO(b/401051826)
10641058
const protocol = parsed.protocol;
10651059

10661060
return {
@@ -1344,33 +1338,28 @@ export class Http2SessionHandler {
13441338
const http2Session = http2.connect(url, opts)
13451339

13461340
http2Session.on('goaway', (errorCode, _, opaqueData) => {
1347-
console.log("GOT SESSION GOAWAY EVENT")
13481341
this.reject(new FirebaseAppError(
1349-
AppErrorCodes.NETWORK_ERROR,
1350-
`Error while making requests: GOAWAY - ${opaqueData.toString()}, Error code: ${errorCode}`
1342+
AppErrorCodes.HTTP2_SESSION_ERROR,
1343+
`Error while making requests: GOAWAY - ${opaqueData?.toString()}, Error code: ${errorCode}`
13511344
));
13521345
})
13531346

13541347
http2Session.on('error', (error) => {
1355-
console.log("GOT SESSION ERROR EVENT")
13561348
this.reject(new FirebaseAppError(
1357-
AppErrorCodes.NETWORK_ERROR,
1358-
`Error while making requests: ${error}`
1349+
AppErrorCodes.HTTP2_SESSION_ERROR,
1350+
`Session error while making requests: ${error}`
13591351
));
13601352
})
13611353

1362-
// Session close should be where we resolve the promise since we no longer need to listen for errors
13631354
http2Session.on('close', () => {
1364-
console.log("GOT SESSION CLOSE EVENT")
1355+
// Resolve current promise
13651356
this.resolve()
13661357
});
1367-
13681358
return http2Session
13691359
}
13701360
return this.http2Session
13711361
}
13721362

1373-
// return the promise tracking events
13741363
public invoke(): Promise<void> {
13751364
return this.promise
13761365
}

src/utils/error.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -377,6 +377,7 @@ export class AppErrorCodes {
377377
public static INVALID_APP_OPTIONS = 'invalid-app-options';
378378
public static INVALID_CREDENTIAL = 'invalid-credential';
379379
public static NETWORK_ERROR = 'network-error';
380+
public static HTTP2_SESSION_ERROR = 'http2-session-error';
380381
public static NETWORK_TIMEOUT = 'network-timeout';
381382
public static NO_APP = 'no-app';
382383
public static UNABLE_TO_PARSE_RESPONSE = 'unable-to-parse-response';

test/integration/messaging.spec.ts

Lines changed: 0 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -101,29 +101,6 @@ describe('admin.messaging', () => {
101101
});
102102
});
103103

104-
it('test uncaught error', async () => {
105-
const messages: Message[] = [message, message, message];
106-
107-
// No longer throws uncatchable error
108-
return getMessaging().sendEach(messages, true)
109-
.then((response) => {
110-
console.log(response.responses)
111-
})
112-
.catch(async (error) => {
113-
// type err = {
114-
// error: any,
115-
// batchResponsePromise: Promise<PromiseSettledResult<SendResponse>[]>
116-
// }
117-
// If batchResponsePromise is undefined then no messages were sent
118-
// The promise should eventally return with the result of each request
119-
console.log("CAUGHT ERROR")
120-
console.log(error)
121-
await error.batchResponsePromise.then((results: any) => {
122-
console.log(results)
123-
})
124-
})
125-
});
126-
127104
it('sendEach(500)', () => {
128105
const messages: Message[] = [];
129106
for (let i = 0; i < 500; i++) {

0 commit comments

Comments
 (0)