diff options
Diffstat (limited to 'u/server/filter')
-rw-r--r-- | u/server/filter/json.ts | 43 | ||||
-rw-r--r-- | u/server/filter/method.ts | 10 | ||||
-rw-r--r-- | u/server/filter/mod.ts | 28 |
3 files changed, 50 insertions, 31 deletions
diff --git a/u/server/filter/json.ts b/u/server/filter/json.ts index c839707..4a2961e 100644 --- a/u/server/filter/json.ts +++ b/u/server/filter/json.ts @@ -3,46 +3,49 @@ import { type IEither, type ITraceable, LogLevel, + Metric, + PenguenoError, type PenguenoRequest, type RequestFilter, type ServerTrace, TraceUtil, } from "@emprespresso/pengueno"; -import { Metric } from "../../trace/mod.ts"; -type JsonTransformer<R, ParsedJson = unknown> = ( - json: ITraceable<ParsedJson, ServerTrace>, -) => IEither<Error, R>; +export interface JsonTransformer<R, ParsedJson = unknown> { + (json: ITraceable<ParsedJson, ServerTrace>): IEither<PenguenoError, R>; +} const ParseJsonMetric = Metric.fromName("JsonParse"); export const jsonModel = <MessageT>( jsonTransformer: JsonTransformer<MessageT>, -): RequestFilter<MessageT, Error> => +): RequestFilter<MessageT> => (r: ITraceable<PenguenoRequest, ServerTrace>) => - r - .bimap(TraceUtil.withMetricTrace(ParseJsonMetric)) + r.bimap(TraceUtil.withMetricTrace(ParseJsonMetric)) .map((j) => Either.fromFailableAsync<Error, MessageT>(j.get().json()) .then((either) => either.mapLeft((errReason) => { j.trace.addTrace(LogLevel.WARN).trace(`${errReason}`); - return new Error("seems to be invalid JSON (>//<) can you fix?"); + return new PenguenoError( + "seems to be invalid JSON (>//<) can you fix?", + 400, + ); }) ) ) - .flatMapAsync( - TraceUtil.promiseify((traceableEitherJson) => - traceableEitherJson.map((t) => - t.get().mapRight(traceableEitherJson.move).flatMap( - jsonTransformer, - ) + .peek( + TraceUtil.promiseify((traceableEither) => + traceableEither.get().mapBoth( + () => traceableEither.trace.trace(ParseJsonMetric.failure), + () => traceableEither.trace.trace(ParseJsonMetric.success), ) ), ) - .peek(TraceUtil.promiseify((traceableEither) => - traceableEither.get().mapBoth( - () => traceableEither.trace.trace(ParseJsonMetric.failure), - () => traceableEither.trace.trace(ParseJsonMetric.success), - ) - )) + .map( + TraceUtil.promiseify((traceableEitherJson) => + traceableEitherJson.get() + .mapRight(traceableEitherJson.move) + .flatMap(jsonTransformer) + ), + ) .get(); diff --git a/u/server/filter/method.ts b/u/server/filter/method.ts index 350f04c..6b0419d 100644 --- a/u/server/filter/method.ts +++ b/u/server/filter/method.ts @@ -1,8 +1,8 @@ import { Either, type ITraceable, - JsonResponse, LogLevel, + PenguenoError, type PenguenoRequest, type RequestFilter, type ServerTrace, @@ -22,7 +22,7 @@ type HttpMethod = export const requireMethod = ( methods: Array<HttpMethod>, -): RequestFilter<HttpMethod, JsonResponse> => +): RequestFilter<HttpMethod> => (req: ITraceable<PenguenoRequest, ServerTrace>) => req.bimap(TraceUtil.withFunctionTrace(requireMethod)) .move(Promise.resolve(req.get())) @@ -32,10 +32,10 @@ export const requireMethod = ( if (!methods.includes(method)) { const msg = "that's not how you pet me (âīšâ)~"; t.trace.addTrace(LogLevel.WARN).trace(msg); - return Either.left<JsonResponse, HttpMethod>( - new JsonResponse(req, msg, { status: 405 }), + return Either.left<PenguenoError, HttpMethod>( + new PenguenoError(msg, 405), ); } - return Either.right<JsonResponse, HttpMethod>(method); + return Either.right<PenguenoError, HttpMethod>(method); })) .get(); diff --git a/u/server/filter/mod.ts b/u/server/filter/mod.ts index 22ddad5..bbf37df 100644 --- a/u/server/filter/mod.ts +++ b/u/server/filter/mod.ts @@ -1,13 +1,29 @@ -import type { - IEither, - ITraceable, - PenguenoRequest, - ServerTrace, +import { + type IEither, + type ITraceable, + LogLevel, + type PenguenoRequest, + type ServerTrace, } from "@emprespresso/pengueno"; +export enum ErrorSource { + USER = LogLevel.WARN, + SYSTEM = LogLevel.ERROR, +} + +export class PenguenoError extends Error { + public readonly source: ErrorSource; + constructor(message: string, public readonly status: number) { + super(message); + this.source = Math.floor(status / 100) === 4 + ? ErrorSource.USER + : ErrorSource.SYSTEM; + } +} + export interface RequestFilter< T, - Err, + Err extends PenguenoError = PenguenoError, RIn = ITraceable<PenguenoRequest, ServerTrace>, > { (req: RIn): Promise<IEither<Err, T>>; |