mirror of
https://github.com/ajnart/homarr.git
synced 2026-01-29 10:49:14 +01:00
fix: fetch timeout for external requests to small (#881)
* fix: fetch timeout for external requests to small * fix: format issue * fix: move clear timeout for fetch to finally
This commit is contained in:
@@ -1,3 +1,4 @@
|
||||
import { fetchWithTimeout } from "@homarr/common";
|
||||
import type { z } from "@homarr/validation";
|
||||
import { validation } from "@homarr/validation";
|
||||
|
||||
@@ -8,7 +9,7 @@ export const locationRouter = createTRPCRouter({
|
||||
.input(validation.location.searchCity.input)
|
||||
.output(validation.location.searchCity.output)
|
||||
.query(async ({ input }) => {
|
||||
const res = await fetch(`https://geocoding-api.open-meteo.com/v1/search?name=${input.query}`);
|
||||
const res = await fetchWithTimeout(`https://geocoding-api.open-meteo.com/v1/search?name=${input.query}`);
|
||||
return (await res.json()) as z.infer<typeof validation.location.searchCity.output>;
|
||||
}),
|
||||
});
|
||||
|
||||
@@ -1,10 +1,11 @@
|
||||
import { fetchWithTimeout } from "@homarr/common";
|
||||
import { validation } from "@homarr/validation";
|
||||
|
||||
import { createTRPCRouter, publicProcedure } from "../../trpc";
|
||||
|
||||
export const weatherRouter = createTRPCRouter({
|
||||
atLocation: publicProcedure.input(validation.widget.weather.atLocationInput).query(async ({ input }) => {
|
||||
const res = await fetch(
|
||||
const res = await fetchWithTimeout(
|
||||
`https://api.open-meteo.com/v1/forecast?latitude=${input.latitude}&longitude=${input.longitude}&daily=weathercode,temperature_2m_max,temperature_2m_min¤t_weather=true&timezone=auto`,
|
||||
);
|
||||
const json: unknown = await res.json();
|
||||
|
||||
16
packages/common/src/fetch-with-timeout.ts
Normal file
16
packages/common/src/fetch-with-timeout.ts
Normal file
@@ -0,0 +1,16 @@
|
||||
/**
|
||||
* Same as fetch, but with a timeout of 10 seconds.
|
||||
* https://stackoverflow.com/questions/46946380/fetch-api-request-timeout
|
||||
* @param param0 fetch arguments
|
||||
* @returns fetch response
|
||||
*/
|
||||
export const fetchWithTimeout = (...[url, requestInit]: Parameters<typeof fetch>) => {
|
||||
const controller = new AbortController();
|
||||
|
||||
// 10 seconds timeout:
|
||||
const timeoutId = setTimeout(() => controller.abort(), 10000);
|
||||
|
||||
return fetch(url, { signal: controller.signal, ...requestInit }).finally(() => {
|
||||
clearTimeout(timeoutId);
|
||||
});
|
||||
};
|
||||
@@ -8,3 +8,4 @@ export * from "./url";
|
||||
export * from "./number";
|
||||
export * from "./error";
|
||||
export * from "./encryption";
|
||||
export * from "./fetch-with-timeout";
|
||||
|
||||
@@ -21,7 +21,8 @@
|
||||
"typecheck": "tsc --noEmit"
|
||||
},
|
||||
"dependencies": {
|
||||
"@homarr/log": "workspace:^0.1.0"
|
||||
"@homarr/log": "workspace:^0.1.0",
|
||||
"@homarr/common": "workspace:^0.1.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@homarr/eslint-config": "workspace:^0.2.0",
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
import { fetchWithTimeout } from "@homarr/common";
|
||||
|
||||
import type { IconRepositoryLicense } from "../types/icon-repository-license";
|
||||
import type { RepositoryIconGroup } from "../types/repository-icon-group";
|
||||
import { IconRepository } from "./icon-repository";
|
||||
@@ -19,7 +21,7 @@ export class GitHubIconRepository extends IconRepository {
|
||||
throw new Error("Repository URLs are required for this repository");
|
||||
}
|
||||
|
||||
const response = await fetch(this.repositoryIndexingUrl);
|
||||
const response = await fetchWithTimeout(this.repositoryIndexingUrl);
|
||||
const listOfFiles = (await response.json()) as GitHubApiResponse;
|
||||
|
||||
return {
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
import { fetchWithTimeout } from "@homarr/common";
|
||||
|
||||
import type { IconRepositoryLicense } from "../types/icon-repository-license";
|
||||
import type { RepositoryIconGroup } from "../types/repository-icon-group";
|
||||
import { IconRepository } from "./icon-repository";
|
||||
@@ -15,7 +17,7 @@ export class JsdelivrIconRepository extends IconRepository {
|
||||
}
|
||||
|
||||
protected async getAllIconsInternalAsync(): Promise<RepositoryIconGroup> {
|
||||
const response = await fetch(this.repositoryIndexingUrl);
|
||||
const response = await fetchWithTimeout(this.repositoryIndexingUrl);
|
||||
const listOfFiles = (await response.json()) as JsdelivrApiResponse;
|
||||
|
||||
return {
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
import { extractErrorMessage } from "@homarr/common";
|
||||
import { extractErrorMessage, fetchWithTimeout } from "@homarr/common";
|
||||
import { logger } from "@homarr/log";
|
||||
|
||||
export const sendPingRequestAsync = async (url: string) => {
|
||||
try {
|
||||
return await fetch(url).then((response) => ({ statusCode: response.status }));
|
||||
return await fetchWithTimeout(url).then((response) => ({ statusCode: response.status }));
|
||||
} catch (error) {
|
||||
logger.error("packages/ping/src/index.ts:", error);
|
||||
return {
|
||||
|
||||
3
pnpm-lock.yaml
generated
3
pnpm-lock.yaml
generated
@@ -868,6 +868,9 @@ importers:
|
||||
|
||||
packages/icons:
|
||||
dependencies:
|
||||
'@homarr/common':
|
||||
specifier: workspace:^0.1.0
|
||||
version: link:../common
|
||||
'@homarr/log':
|
||||
specifier: workspace:^0.1.0
|
||||
version: link:../log
|
||||
|
||||
Reference in New Issue
Block a user