Initial commit (unpacked platform)
This commit is contained in:
@@ -0,0 +1,39 @@
|
||||
import type { ZodType } from "zod";
|
||||
|
||||
/** Applikationsfel med HTTP-status och maskinläsbar kod. */
|
||||
export class ApiError extends Error {
|
||||
constructor(
|
||||
public readonly statusCode: number,
|
||||
public readonly code: string,
|
||||
message: string,
|
||||
public readonly details?: unknown,
|
||||
) {
|
||||
super(message);
|
||||
this.name = "ApiError";
|
||||
}
|
||||
}
|
||||
|
||||
export const errors = {
|
||||
badRequest: (msg: string, details?: unknown) => new ApiError(400, "BAD_REQUEST", msg, details),
|
||||
unauthorized: (msg = "Ogiltig eller saknad autentisering") =>
|
||||
new ApiError(401, "UNAUTHORIZED", msg),
|
||||
forbidden: (msg = "Åtkomst nekad") => new ApiError(403, "FORBIDDEN", msg),
|
||||
notFound: (msg = "Resursen finns inte") => new ApiError(404, "NOT_FOUND", msg),
|
||||
conflict: (msg: string) => new ApiError(409, "CONFLICT", msg),
|
||||
quotaExceeded: (msg: string) => new ApiError(429, "QUOTA_EXCEEDED", msg),
|
||||
paymentRequired: (msg: string) => new ApiError(402, "PREMIUM_REQUIRED", msg),
|
||||
internal: (msg = "Internt fel") => new ApiError(500, "INTERNAL", msg),
|
||||
};
|
||||
|
||||
/**
|
||||
* Validera indata mot ett Zod-schema. Kastar 400 med detaljer vid fel.
|
||||
* Medvetet vald i stället för type-provider: färre rörliga delar i
|
||||
* major-versionsgränser, samma säkerhet (se docs/beslutslogg.md D-011).
|
||||
*/
|
||||
export function parse<T>(schema: ZodType<T>, data: unknown, what = "indata"): T {
|
||||
const result = schema.safeParse(data);
|
||||
if (!result.success) {
|
||||
throw new ApiError(400, "VALIDATION_ERROR", `Ogiltig ${what}`, result.error.issues);
|
||||
}
|
||||
return result.data;
|
||||
}
|
||||
Reference in New Issue
Block a user