refactor(logs): move to core package (#4586)

This commit is contained in:
Meier Lukas
2025-12-16 23:37:44 +01:00
committed by GitHub
parent d86af072bf
commit d348abfe4a
145 changed files with 971 additions and 708 deletions

View File

@@ -1,7 +1,5 @@
import { AxiosError } from "axios";
import { logger } from "@homarr/log";
import type { AnyRequestError } from "../request-error";
import { RequestError } from "../request-error";
import { ResponseError } from "../response-error";
@@ -9,11 +7,15 @@ import { matchErrorCode } from "./fetch-http-error-handler";
import { HttpErrorHandler } from "./http-error-handler";
export class AxiosHttpErrorHandler extends HttpErrorHandler {
constructor() {
super("axios");
}
handleRequestError(error: unknown): AnyRequestError | undefined {
if (!(error instanceof AxiosError)) return undefined;
if (error.code === undefined) return undefined;
logger.debug("Received Axios request error", {
this.logRequestError({
code: error.code,
message: error.message,
});
@@ -28,8 +30,7 @@ export class AxiosHttpErrorHandler extends HttpErrorHandler {
handleResponseError(error: unknown): ResponseError | undefined {
if (!(error instanceof AxiosError)) return undefined;
if (error.response === undefined) return undefined;
logger.debug("Received Axios response error", {
this.logResponseError({
status: error.response.status,
url: error.response.config.url,
message: error.message,

View File

@@ -1,5 +1,3 @@
import { logger } from "@homarr/log";
import { objectEntries } from "../../../object";
import type { Modify } from "../../../types";
import type { AnyRequestError, AnyRequestErrorInput, RequestErrorCode, RequestErrorReason } from "../request-error";
@@ -9,13 +7,13 @@ import { HttpErrorHandler } from "./http-error-handler";
export class FetchHttpErrorHandler extends HttpErrorHandler {
constructor(private type = "undici") {
super();
super(type);
}
handleRequestError(error: unknown): AnyRequestError | undefined {
if (!isTypeErrorWithCode(error)) return undefined;
logger.debug(`Received ${this.type} request error`, {
this.logRequestError({
code: error.cause.code,
});

View File

@@ -1,7 +1,24 @@
import type { Logger } from "@homarr/core/infrastructure/logs";
import { createLogger } from "@homarr/core/infrastructure/logs";
import type { AnyRequestError } from "../request-error";
import type { ResponseError } from "../response-error";
export abstract class HttpErrorHandler {
protected logger: Logger;
constructor(type: string) {
this.logger = createLogger({ module: "httpErrorHandler", type });
}
protected logRequestError<T extends { code: string }>(metadata: T) {
this.logger.debug("Received request error", metadata);
}
protected logResponseError<T extends { status: number; url: string | undefined }>(metadata: T) {
this.logger.debug("Received response error", metadata);
}
abstract handleRequestError(error: unknown): AnyRequestError | undefined;
abstract handleResponseError(error: unknown): ResponseError | undefined;
}

View File

@@ -1,7 +1,5 @@
import { FetchError } from "node-fetch";
import { logger } from "@homarr/log";
import { RequestError } from "../request-error";
import type { AnyRequestError } from "../request-error";
import type { ResponseError } from "../response-error";
@@ -15,14 +13,14 @@ import { HttpErrorHandler } from "./http-error-handler";
*/
export class NodeFetchHttpErrorHandler extends HttpErrorHandler {
constructor(private type = "node-fetch") {
super();
super(type);
}
handleRequestError(error: unknown): AnyRequestError | undefined {
if (!(error instanceof FetchError)) return undefined;
if (error.code === undefined) return undefined;
logger.debug(`Received ${this.type} request error`, {
this.logRequestError({
code: error.code,
message: error.message,
});

View File

@@ -5,6 +5,10 @@ import { ResponseError } from "../response-error";
import { HttpErrorHandler } from "./http-error-handler";
export class OctokitHttpErrorHandler extends HttpErrorHandler {
constructor() {
super("octokit");
}
/**
* I wasn't able to get a request error triggered. Therefore we ignore them for now
* and just forward them as unknown errors
@@ -16,6 +20,11 @@ export class OctokitHttpErrorHandler extends HttpErrorHandler {
handleResponseError(error: unknown): ResponseError | undefined {
if (!(error instanceof OctokitRequestError)) return undefined;
this.logResponseError({
status: error.status,
url: error.response?.url,
});
return new ResponseError({
status: error.status,
url: error.response?.url,

View File

@@ -1,7 +1,5 @@
import { FetchError } from "ofetch";
import { logger } from "@homarr/log";
import type { AnyRequestError } from "../request-error";
import { ResponseError } from "../response-error";
import { FetchHttpErrorHandler } from "./fetch-http-error-handler";
@@ -14,6 +12,10 @@ import { HttpErrorHandler } from "./http-error-handler";
* It is for example used within the ctrl packages like qbittorrent, deluge, transmission, etc.
*/
export class OFetchHttpErrorHandler extends HttpErrorHandler {
constructor() {
super("ofetch");
}
handleRequestError(error: unknown): AnyRequestError | undefined {
if (!(error instanceof FetchError)) return undefined;
if (!(error.cause instanceof TypeError)) return undefined;
@@ -28,7 +30,7 @@ export class OFetchHttpErrorHandler extends HttpErrorHandler {
if (!(error instanceof FetchError)) return undefined;
if (error.response === undefined) return undefined;
logger.debug("Received ofetch response error", {
this.logResponseError({
status: error.response.status,
url: error.response.url,
});

View File

@@ -1,11 +1,13 @@
import { logger } from "@homarr/log";
import type { AnyRequestError } from "../request-error";
import { ResponseError } from "../response-error";
import { HttpErrorHandler } from "./http-error-handler";
import { NodeFetchHttpErrorHandler } from "./node-fetch-http-error-handler";
export class TsdavHttpErrorHandler extends HttpErrorHandler {
constructor() {
super("tsdav");
}
handleRequestError(error: unknown): AnyRequestError | undefined {
return new NodeFetchHttpErrorHandler("tsdav").handleRequestError(error);
}
@@ -16,8 +18,9 @@ export class TsdavHttpErrorHandler extends HttpErrorHandler {
// https://github.com/natelindev/tsdav/blob/bf33f04b1884694d685ee6f2b43fe9354b12d167/src/account.ts#L86
if (error.message !== "Invalid credentials") return undefined;
logger.debug("Received tsdav response error", {
this.logResponseError({
status: 401,
url: undefined,
});
return new ResponseError({ status: 401, url: "?" });

View File

@@ -1,13 +1,15 @@
import { logger } from "@homarr/log";
import { ParseError } from "../parse-error";
import { ParseErrorHandler } from "./parse-error-handler";
export class JsonParseErrorHandler extends ParseErrorHandler {
constructor() {
super("json");
}
handleParseError(error: unknown): ParseError | undefined {
if (!(error instanceof SyntaxError)) return undefined;
logger.debug("Received JSON parse error", {
this.logParseError({
message: error.message,
});

View File

@@ -1,5 +1,17 @@
import type { Logger } from "@homarr/core/infrastructure/logs";
import { createLogger } from "@homarr/core/infrastructure/logs";
import type { ParseError } from "../parse-error";
export abstract class ParseErrorHandler {
protected logger: Logger;
constructor(type: string) {
this.logger = createLogger({ module: "parseErrorHandler", type });
}
protected logParseError(metadata?: Record<string, unknown>) {
this.logger.debug("Received parse error", metadata);
}
abstract handleParseError(error: unknown): ParseError | undefined;
}

View File

@@ -1,12 +1,14 @@
import { fromError } from "zod-validation-error";
import { ZodError } from "zod/v4";
import { logger } from "@homarr/log";
import { ParseError } from "../parse-error";
import { ParseErrorHandler } from "./parse-error-handler";
export class ZodParseErrorHandler extends ParseErrorHandler {
constructor() {
super("zod");
}
handleParseError(error: unknown): ParseError | undefined {
if (!(error instanceof ZodError)) return undefined;
@@ -17,7 +19,7 @@ export class ZodParseErrorHandler extends ParseErrorHandler {
prefix: null,
}).toString();
logger.debug("Received Zod parse error");
this.logParseError();
return new ParseError(message, { cause: error });
}