diff --git a/src/handlers.js b/src/handlers.js index 9b3484c..18f4b3e 100644 --- a/src/handlers.js +++ b/src/handlers.js @@ -3,10 +3,20 @@ import { params } from './params'; const postApiNotify = async ({ env, request }) => { const { errors = [], ...rest } = await params(request); - await mail({ - env, - ...rest, - }); + try { + await mail({ + env, + ...rest, + }); + } catch (e) { + return new Response(JSON.stringify({ error: e.message }), { + headers: { + 'Content-Type': 'application/json', + }, + status: 400, + }); + } + const response = { ...rest, ...(errors.length && { errors }), diff --git a/src/handlers.spec.js b/src/handlers.spec.js index 49c71ad..09486c1 100644 --- a/src/handlers.spec.js +++ b/src/handlers.spec.js @@ -5,10 +5,10 @@ import { payload } from './mail'; describe('handlers', () => { beforeAll(() => { - global.fetch = vi.fn(); + global.fetch = vi.fn().mockImplementation(() => new Response()); }); - it('400', async () => { + it('400 if missing required parameters', async () => { const request = new Request('http://example.com/api/notify', { method: 'POST', headers: { @@ -23,6 +23,37 @@ describe('handlers', () => { ); }); + it('400 if invalid to: address', async () => { + const request = new Request('http://example.com/api/notify', { + method: 'POST', + body: JSON.stringify({ to: 'invalid email', subject: 'valid subject' }), + headers: { + 'Content-Type': 'application/json', + }, + }); + + global.fetch.mockImplementationOnce(() => { + return new Response( + JSON.stringify({ + errors: [ + { + message: 'Does not contain a valid address.', + field: 'personalizations.0.to.0.email', + help: 'http://sendgrid.com/docs/API_Reference/Web_API_v3/Mail/errors.html#message.personalizations.to', + }, + ], + }), + { status: 400 }, + ); + }); + + const response = await handler({ request }); + expect(await response.status).toEqual(400); + expect(await response.json()).toEqual( + expect.objectContaining({ error: 'Does not contain a valid address.' }), + ); + }); + it('404', async () => { const request = new Request('http://example.com/undefined-route'); const response = await handler({ request }); diff --git a/src/mail.js b/src/mail.js index d18f3f4..c11db55 100644 --- a/src/mail.js +++ b/src/mail.js @@ -23,7 +23,7 @@ export const payload = ({ subject, to, type, body, attachments }) => ({ * @returns Promise */ export const mail = async ({ env = {}, ...rest }) => { - await fetch('https://api.sendgrid.com/v3/mail/send', { + const response = await fetch('https://api.sendgrid.com/v3/mail/send', { headers: { Authorization: `Bearer ${env.SENDGRID_API_KEY}`, 'Content-Type': 'application/json', @@ -31,4 +31,7 @@ export const mail = async ({ env = {}, ...rest }) => { method: 'POST', body: JSON.stringify(payload({ ...rest })), }); + if (response.status > 299) { + throw new Error((await response.json()).errors[0].message); + } };