From c5cd379b8aa6ec98458456cc6d50e1dd7548c5f1 Mon Sep 17 00:00:00 2001 From: wea_ondara Date: Sat, 25 Nov 2023 17:08:13 +0100 Subject: [PATCH] backend: properly catch exception in controllers so that the server does not crash --- backend/src/controller/AniListController.ts | 4 +- .../src/controller/MangaUpdatesController.ts | 170 ++++++++++-------- 2 files changed, 93 insertions(+), 81 deletions(-) diff --git a/backend/src/controller/AniListController.ts b/backend/src/controller/AniListController.ts index e1e357b..570ff71 100644 --- a/backend/src/controller/AniListController.ts +++ b/backend/src/controller/AniListController.ts @@ -13,9 +13,9 @@ export default class AniListController { const fromApiText = await fromApi.text(); res.status(fromApi.status).send(fromApiText); + next(); } catch (e) { - console.error(e); + next(e); } - next(); } } \ No newline at end of file diff --git a/backend/src/controller/MangaUpdatesController.ts b/backend/src/controller/MangaUpdatesController.ts index 5dae4ba..315b4c8 100644 --- a/backend/src/controller/MangaUpdatesController.ts +++ b/backend/src/controller/MangaUpdatesController.ts @@ -9,99 +9,111 @@ export class MangaUpdatesController { } async search(req: Request, res: Response, next: NextFunction): Promise { - const bjson = req.body; - if (bjson['stype'] !== 'title' || bjson['type'] !== 'Manga' || !bjson['search']?.trim().length) { - res.status(400).send('Only {stype: "title", type: "Manga", search: "some title"} allowed!'); + try { + const bjson = req.body; + if (bjson['stype'] !== 'title' || bjson['type'] !== 'Manga' || !bjson['search']?.trim().length) { + res.status(400).send('Only {stype: "title", type: "Manga", search: "some title"} allowed!'); + next('router'); + return; + } + + const fromCache = this.cache.getSearchByTitle(bjson['search']); + if (fromCache) { + res.status(200).setHeader('Content-Type', 'application/json').send(fromCache); + next('router'); + return; + } + + //throttle + await new Promise((r) => setTimeout(r, 1000)); + + //fetch from manga updates + const fromApi = await fetch('https://api.mangaupdates.com/v1/series/search', { + method: 'POST', + headers: { + 'Content-Type': 'application/json', + }, + body: JSON.stringify(bjson), + }); + + if (fromApi.status !== 200) { + res.status(fromApi.status).send(fromApi.body); + next('router'); + return; + } + + const fromApiJson = await fromApi.text(); + this.cache.putSearchByTitle(bjson['search'], fromApiJson); + + res.status(200).setHeader('Content-Type', 'application/json').send(fromApiJson); next('router'); - return; + } catch (e) { + next(e); } - - const fromCache = this.cache.getSearchByTitle(bjson['search']); - if (fromCache) { - res.status(200).setHeader('Content-Type', 'application/json').send(fromCache); - next('router'); - return; - } - - //throttle - await new Promise((r) => setTimeout(r, 1000)); - - //fetch from manga updates - const fromApi = await fetch('https://api.mangaupdates.com/v1/series/search', { - method: 'POST', - headers: { - 'Content-Type': 'application/json', - }, - body: JSON.stringify(bjson), - }); - - if (fromApi.status !== 200) { - res.status(fromApi.status).send(fromApi.body); - next('router'); - return; - } - - const fromApiJson = await fromApi.text(); - this.cache.putSearchByTitle(bjson['search'], fromApiJson); - - res.status(200).setHeader('Content-Type', 'application/json').send(fromApiJson); - next('router'); } async getById(req: Request, res: Response, next: NextFunction): Promise { - const id = req.params.id!.toLowerCase(); + try { + const id = req.params.id!.toLowerCase(); - const fromCache = this.cache.getSeriesById(id); - if (fromCache) { - res.status(200).setHeader('Content-Type', 'application/json').send(fromCache); + const fromCache = this.cache.getSeriesById(id); + if (fromCache) { + res.status(200).setHeader('Content-Type', 'application/json').send(fromCache); + next(); + return; + } + + //throttle + await new Promise((r) => setTimeout(r, 1000)); + + //fetch from manga updates + const fromApi = await fetch('https://api.mangaupdates.com/v1/series/' + id); + if (fromApi.status !== 200) { + res.status(fromApi.status).send(fromApi.body); + next(); + return; + } + + const fromApiJson = await fromApi.text(); + this.cache.putSeriesById(id, fromApiJson); + + res.status(200).setHeader('Content-Type', 'application/json').send(fromApiJson); next(); - return; + } catch (e) { + next(e); } - - //throttle - await new Promise((r) => setTimeout(r, 1000)); - - //fetch from manga updates - const fromApi = await fetch('https://api.mangaupdates.com/v1/series/' + id); - if (fromApi.status !== 200) { - res.status(fromApi.status).send(fromApi.body); - next(); - return; - } - - const fromApiJson = await fromApi.text(); - this.cache.putSeriesById(id, fromApiJson); - - res.status(200).setHeader('Content-Type', 'application/json').send(fromApiJson); - next(); } async getGroupById(req: Request, res: Response, next: NextFunction): Promise { - const id = req.params.id!.toLowerCase(); + try { + const id = req.params.id!.toLowerCase(); - const fromCache = this.cache.getSeriesGroupsById(id); - if (fromCache) { - res.status(200).setHeader('Content-Type', 'application/json').send(fromCache); + const fromCache = this.cache.getSeriesGroupsById(id); + if (fromCache) { + res.status(200).setHeader('Content-Type', 'application/json').send(fromCache); + next(); + return; + } + + //throttle + await new Promise((r) => setTimeout(r, 1000)); + + //fetch from manga updates + const fromApi = await fetch('https://api.mangaupdates.com/v1/series/' + id + '/groups'); + if (fromApi.status !== 200) { + res.status(fromApi.status).send(fromApi.body); + next(); + return; + } + + const fromApiJson = await fromApi.text(); + this.cache.putSeriesGroupsById(id, fromApiJson); + + res.status(200).setHeader('Content-Type', 'application/json').send(fromApiJson); next(); - return; + } catch (e) { + next(e); } - - //throttle - await new Promise((r) => setTimeout(r, 1000)); - - //fetch from manga updates - const fromApi = await fetch('https://api.mangaupdates.com/v1/series/' + id + '/groups'); - if (fromApi.status !== 200) { - res.status(fromApi.status).send(fromApi.body); - next(); - return; - } - - const fromApiJson = await fromApi.text(); - this.cache.putSeriesGroupsById(id, fromApiJson); - - res.status(200).setHeader('Content-Type', 'application/json').send(fromApiJson); - next(); } async getSeriesIdFromWebsiteId(req: Request, res: Response, next: NextFunction): Promise {