From 2f760fe218b438068198e19af22500b85e3e6fc1 Mon Sep 17 00:00:00 2001 From: Nathan Simpson Date: Wed, 4 Oct 2023 22:50:47 +1100 Subject: [PATCH] Ensure errors are returned as response --- components/Home/Dribbble/Dribbble.tsx | 2 - pages/api/get-dribbble-shots.ts | 59 ++++++++++++++------------- 2 files changed, 30 insertions(+), 31 deletions(-) diff --git a/components/Home/Dribbble/Dribbble.tsx b/components/Home/Dribbble/Dribbble.tsx index ffb63a9..e0caec8 100644 --- a/components/Home/Dribbble/Dribbble.tsx +++ b/components/Home/Dribbble/Dribbble.tsx @@ -1,5 +1,3 @@ -import React from 'react'; - import { Stack } from '../../ui/box'; import { Heading, Text } from '../../ui/typography'; import { TextLink } from '../../TextLink'; diff --git a/pages/api/get-dribbble-shots.ts b/pages/api/get-dribbble-shots.ts index 44d8f4e..e32d426 100644 --- a/pages/api/get-dribbble-shots.ts +++ b/pages/api/get-dribbble-shots.ts @@ -8,10 +8,14 @@ type DribbbleShot = { link: string; }; -type Data = { +type ResponseData = { shots: DribbbleShot[]; }; +type ResponseError = { + error: string; +}; + // Return type from Dribbble API type DribbbleApiShot = { description: string; @@ -25,38 +29,35 @@ type DribbbleApiShot = { const ACCESS_TOKEN = process.env.DRIBBBLE_ACCESS_TOKEN; const API_ENDPOINT = `https://api.dribbble.com/v2/user/shots?access_token=${ACCESS_TOKEN}`; -const getDribbbleShots = async (): Promise => { - const dribbbleShots = fetch(API_ENDPOINT, { - headers: { Accept: 'application/json' } - }) - .then((response) => response.json()) - - .then((data) => { - return (data as DribbbleApiShot[]) - .map((shot) => ({ - description: shot.description.replace(/(<([^>]+)>)/gi, ''), - imageUrl: shot.images.normal, - link: - shot.images && (shot.images.hidpi || shot.images.normal) - ? shot.images.hidpi || shot.images.normal - : shot.html_url - })) - .filter((shot) => !shot.imageUrl.includes('.gif')); - }); - - return dribbbleShots; +const formatShots = (shots: DribbbleApiShot[]): DribbbleShot[] => { + return shots + .map((shot) => ({ + description: shot.description.replace(/(<([^>]+)>)/gi, ''), + imageUrl: shot.images.normal, + link: + shot.images && (shot.images.hidpi || shot.images.normal) + ? shot.images.hidpi || shot.images.normal + : shot.html_url + })) + .filter((shot) => !shot.imageUrl.includes('.gif')); }; export default async function handler( req: NextApiRequest, - res: NextApiResponse + res: NextApiResponse ) { - return getDribbbleShots() - .then((shots) => { - res.status(200).json({ shots }); + await fetch(API_ENDPOINT, { + headers: { Accept: 'application/json' } + }) + .then((response) => { + if (!response.ok) { + throw new Error("Unsuccessful response from Dribbble's API"); + } + + return response.json().then((data) => { + const formatted = formatShots(data as DribbbleApiShot[]); + return res.status(200).json({ shots: formatted }); + }); }) - .catch((error) => ({ - statusCode: 422, - body: JSON.stringify(error) - })); + .catch((error) => res.status(422).json({ error })); }