feat: add more error handling

This commit is contained in:
2024-06-07 23:13:30 -04:00
parent 6fd2cc4feb
commit c35c9b9e09
9 changed files with 71 additions and 66 deletions

View File

@@ -29,8 +29,8 @@ describe('requests the "/episodes" route', () => {
},
);
expect(response.json()).resolves.toEqual({ success: false });
expect(response.status).toBe(404);
expect(response.json()).resolves.toEqual({ success: true, result: [] });
expect(response.status).toBe(200);
});
it("Anify is disabled, returns no episode list from Anify", async () => {
@@ -42,8 +42,8 @@ describe('requests the "/episodes" route', () => {
},
);
expect(response.json()).resolves.toEqual({ success: false });
expect(response.status).toBe(404);
expect(response.json()).resolves.toEqual({ success: true, result: [] });
expect(response.status).toBe(200);
});
it("with list of episodes from Consumet", async () => {
@@ -100,7 +100,7 @@ describe('requests the "/episodes" route', () => {
it("with no episodes from all sources", async () => {
const response = await app.request("/episodes/-1");
expect(response.json()).resolves.toEqual({ success: false });
expect(response.status).toBe(404);
expect(response.json()).resolves.toEqual({ success: true, result: [] });
expect(response.status).toBe(200);
});
});

View File

@@ -33,13 +33,13 @@ const route = createRoute({
},
description: "Returns a list of episodes",
},
404: {
500: {
content: {
"application/json": {
schema: ErrorResponseSchema,
},
},
description: "Returns an empty list because episodes not found",
description: "Error fetching episodes",
},
},
});
@@ -49,7 +49,7 @@ const app = new OpenAPIHono<Env>();
app.openapi(route, async (c) => {
const aniListId = Number(c.req.param("aniListId"));
const episodes = await fetchFromMultipleSources([
const { result: episodes, errors } = await fetchFromMultipleSources([
() => {
const isAnifyEnabled = readEnvVariable<boolean>(c.env, "ENABLE_ANIFY");
return getEpisodesFromAnify(isAnifyEnabled, aniListId);
@@ -64,13 +64,13 @@ app.openapi(route, async (c) => {
),
]);
if (!episodes) {
return c.json(ErrorResponse, { status: 404 });
if (errors?.length > 0) {
return c.json(ErrorResponse, { status: 500 });
}
return c.json({
success: true,
result: episodes,
result: episodes ?? [],
});
});

View File

@@ -19,12 +19,13 @@ describe('requests the "/search" route', () => {
});
it("query that returns no results", async () => {
const response = await app.request("/search?query=");
const response = await app.request("/search?query=a");
expect(response.json()).resolves.toEqual({
success: false,
success: true,
results: [],
hasNextPage: false,
});
expect(response.status).toBe(200);
});
});

View File

@@ -39,12 +39,17 @@ app.openapi(route, async (c) => {
const page = Number(c.req.query("page") ?? 1);
const limit = Number(c.req.query("limit") ?? 10);
const response = await fetchFromMultipleSources([
const { result: response, errors } = await fetchFromMultipleSources([
() => fetchSearchResultsFromAnilist(query, page, limit),
() => fetchSearchResultsFromAmvstrm(query, page, limit),
]);
if (!response) {
return c.json({ success: false, results: [], hasNextPage: false }, 200);
return c.json({
success: (errors ?? []).length === 0,
results: [],
hasNextPage: false,
});
}
return c.json(

View File

@@ -11,52 +11,38 @@ export async function fetchTitleFromAmvstrm(
console.error("Failed to get missing information from Anify", err);
return null;
}),
]).then(
async ([
{
id,
idMal,
title: { english: englishTitle, userPreferred: userPreferredTitle },
description,
episodes,
genres,
status,
bannerImage,
coverImage: {
extraLarge: extraLargeCoverImage,
large: largeCoverImage,
medium: mediumCoverImage,
},
countryOfOrigin,
nextair: nextAiringEpisode,
score: { averageScore },
]).then(async ([amvstrmInfo, anifyInfo]) => {
if (amvstrmInfo.code >= 400) {
console.error(
`Error trying to load title from amvstrm; aniListId: ${aniListId}, code: ${amvstrmInfo.code}, message: ${amvstrmInfo.message}`,
);
return undefined;
}
return {
id: amvstrmInfo.id,
idMal: amvstrmInfo.idMal,
title: {
userPreferred: amvstrmInfo.title.userPreferred,
english: amvstrmInfo.title.english,
},
anifyInfo,
]) => {
return {
id,
idMal,
title: {
userPreferred: userPreferredTitle,
english: englishTitle,
},
description,
episodes,
genres,
status,
averageScore,
bannerImage: bannerImage ?? anifyInfo?.bannerImage,
coverImage: {
extraLarge: extraLargeCoverImage,
large: largeCoverImage,
medium: mediumCoverImage,
},
countryOfOrigin: countryOfOrigin ?? anifyInfo?.countryOfOrigin,
nextAiringEpisode,
mediaListEntry: null,
};
},
);
description: amvstrmInfo.description,
episodes: amvstrmInfo.episodes,
genres: amvstrmInfo.genres,
status: amvstrmInfo.status,
averageScore: amvstrmInfo.score.averageScore,
bannerImage: amvstrmInfo.bannerImage ?? anifyInfo?.bannerImage,
coverImage: {
extraLarge: amvstrmInfo.coverImage.extraLarge,
large: amvstrmInfo.coverImage.large,
medium: amvstrmInfo.coverImage.medium,
},
countryOfOrigin:
amvstrmInfo.countryOfOrigin ?? anifyInfo?.countryOfOrigin,
nextAiringEpisode: amvstrmInfo.nextair,
mediaListEntry: null,
};
});
}
type AnifyInformation = {

View File

@@ -28,5 +28,12 @@ export async function fetchTitleFromAnilist(
return client
.request(GetTitleQuery, { id }, headers)
.then((data) => data?.Media ?? undefined);
.then((data) => data?.Media ?? undefined)
.catch((error) => {
if (error.message.includes("Not Found")) {
return undefined;
}
throw error;
});
}

View File

@@ -3,6 +3,7 @@ import { OpenAPIHono, createRoute, z } from "@hono/zod-openapi";
import { fetchFromMultipleSources } from "~/libs/fetchFromMultipleSources";
import {
AniListIdQuerySchema,
ErrorResponse,
ErrorResponseSchema,
SuccessResponseSchema,
} from "~/types/schema";
@@ -47,12 +48,17 @@ app.openapi(route, async (c) => {
const aniListId = Number(c.req.query("id"));
const aniListToken = c.req.header("X-AniList-Token");
const title = await fetchFromMultipleSources([
const { result: title, errors } = await fetchFromMultipleSources([
() => fetchTitleFromAnilist(aniListId, aniListToken ?? undefined),
() => fetchTitleFromAmvstrm(aniListId),
]);
if (errors?.length > 0) {
return c.json(ErrorResponse, { status: 500 });
}
if (!title) {
return c.json({ success: false }, 404);
return c.json(ErrorResponse, 404);
}
return c.json({ success: true, result: title }, 200);

View File

@@ -7,7 +7,7 @@ export function getAmvstrmSearchResults() {
const url = new URL(urlString);
const query = url.searchParams.get("q");
if (!query) {
if (!query || query === "a") {
return HttpResponse.json({
code: 200,
message: "success",

View File

@@ -4,7 +4,7 @@ export function getAnilistSearchResults() {
return graphql.query("Search", ({ variables: { query, page } }) => {
console.log(`Intercepting Search query with ${query} and page ${page}`);
if (!query || query === "amvstrm") {
if (!query || query === "a" || query === "amvstrm") {
return HttpResponse.json({
data: {
Page: {