backend: properly catch exception in controllers so that the server does not crash

This commit is contained in:
wea_ondara
2023-11-25 17:08:13 +01:00
parent 9c0b266cbb
commit c5cd379b8a
2 changed files with 93 additions and 81 deletions

View File

@@ -13,9 +13,9 @@ export default class AniListController {
const fromApiText = await fromApi.text(); const fromApiText = await fromApi.text();
res.status(fromApi.status).send(fromApiText); res.status(fromApi.status).send(fromApiText);
next();
} catch (e) { } catch (e) {
console.error(e); next(e);
} }
next();
} }
} }

View File

@@ -9,99 +9,111 @@ export class MangaUpdatesController {
} }
async search(req: Request, res: Response, next: NextFunction): Promise<void> { async search(req: Request, res: Response, next: NextFunction): Promise<void> {
const bjson = req.body; try {
if (bjson['stype'] !== 'title' || bjson['type'] !== 'Manga' || !bjson['search']?.trim().length) { const bjson = req.body;
res.status(400).send('Only {stype: "title", type: "Manga", search: "some title"} allowed!'); 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'); 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<void> { async getById(req: Request, res: Response, next: NextFunction): Promise<void> {
const id = req.params.id!.toLowerCase(); try {
const id = req.params.id!.toLowerCase();
const fromCache = this.cache.getSeriesById(id); const fromCache = this.cache.getSeriesById(id);
if (fromCache) { if (fromCache) {
res.status(200).setHeader('Content-Type', 'application/json').send(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(); 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<void> { async getGroupById(req: Request, res: Response, next: NextFunction): Promise<void> {
const id = req.params.id!.toLowerCase(); try {
const id = req.params.id!.toLowerCase();
const fromCache = this.cache.getSeriesGroupsById(id); const fromCache = this.cache.getSeriesGroupsById(id);
if (fromCache) { if (fromCache) {
res.status(200).setHeader('Content-Type', 'application/json').send(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(); 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<void> { async getSeriesIdFromWebsiteId(req: Request, res: Response, next: NextFunction): Promise<void> {