mirror of
https://dev.azure.com/hugendubel/ISA/_git/ISA-Frontend
synced 2025-12-31 09:37:15 +01:00
♻️ refactor: improve ResponseArgs validation with Zod schema
- Replace manual type checking with Zod schema validation in isResponseArgs helper - Simplify error handling logic in catchResponseArgsErrorPipe operator - Remove redundant conditional checks by leveraging Zod's safeParse - Remove unused ResponseArgs import from operator file This improves type safety and validation robustness by using a declarative schema-based approach.
This commit is contained in:
@@ -1,11 +1,13 @@
|
|||||||
|
import z from 'zod';
|
||||||
import { ResponseArgs } from '../models';
|
import { ResponseArgs } from '../models';
|
||||||
|
|
||||||
|
const ResponseArgsSchema = z.object({
|
||||||
|
error: z.boolean(),
|
||||||
|
message: z.string().optional(),
|
||||||
|
invalidProperties: z.record(z.string()).optional(),
|
||||||
|
result: z.any().optional(),
|
||||||
|
});
|
||||||
|
|
||||||
export function isResponseArgs<T>(args: any): args is ResponseArgs<T> {
|
export function isResponseArgs<T>(args: any): args is ResponseArgs<T> {
|
||||||
return (
|
return ResponseArgsSchema.safeParse(args).success;
|
||||||
args &&
|
|
||||||
typeof args === 'object' &&
|
|
||||||
'error' in args &&
|
|
||||||
'invalidProperties' in args &&
|
|
||||||
'message' in args
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,53 +1,43 @@
|
|||||||
import { catchError, mergeMap } from 'rxjs/operators';
|
import { catchError, mergeMap } from 'rxjs/operators';
|
||||||
import { OperatorFunction, throwError, pipe } from 'rxjs';
|
import { OperatorFunction, throwError, pipe } from 'rxjs';
|
||||||
import { ResponseArgsError } from '../errors';
|
import { ResponseArgsError } from '../errors';
|
||||||
import { HttpErrorResponse } from '@angular/common/http';
|
import { HttpErrorResponse } from '@angular/common/http';
|
||||||
import { ResponseArgs } from '../models';
|
import { isResponseArgs } from '../helpers';
|
||||||
import { isResponseArgs } from '../helpers';
|
|
||||||
|
/**
|
||||||
/**
|
*
|
||||||
*
|
* Operator that catches errors from an observable stream and transforms them into
|
||||||
* Operator that catches errors from an observable stream and transforms them into
|
*
|
||||||
*
|
* `ResponseArgsError` instances when applicable.
|
||||||
* `ResponseArgsError` instances when applicable.
|
* This operator is useful for handling HTTP errors that return a structured
|
||||||
* This operator is useful for handling HTTP errors that return a structured
|
* response conforming to the `ResponseArgs` interface.
|
||||||
* response conforming to the `ResponseArgs` interface.
|
*
|
||||||
*
|
* If the error is already a `ResponseArgsError`, it is re-thrown as is.
|
||||||
* If the error is already a `ResponseArgsError`, it is re-thrown as is.
|
* If the error is an `HttpErrorResponse` with a valid `ResponseArgs` payload,
|
||||||
* If the error is an `HttpErrorResponse` with a valid `ResponseArgs` payload,
|
* it creates and throws a new `ResponseArgsError`.
|
||||||
* it creates and throws a new `ResponseArgsError`.
|
* For all other error types, it re-throws the original error.
|
||||||
* For all other error types, it re-throws the original error.
|
*
|
||||||
*
|
*/
|
||||||
*/
|
export const catchResponseArgsErrorPipe = <T>(): OperatorFunction<T, T> =>
|
||||||
export const catchResponseArgsErrorPipe = <T>(): OperatorFunction<T, T> =>
|
pipe(
|
||||||
pipe(
|
catchError((err: unknown) => {
|
||||||
catchError((err: unknown) => {
|
if (err instanceof ResponseArgsError) {
|
||||||
if (err instanceof ResponseArgsError) {
|
return throwError(() => err);
|
||||||
return throwError(() => err);
|
}
|
||||||
}
|
|
||||||
|
if (err instanceof HttpErrorResponse) {
|
||||||
if (err instanceof HttpErrorResponse && err.error) {
|
const payload = err.error;
|
||||||
const payload = err.error as Partial<ResponseArgs<unknown>>;
|
if (isResponseArgs(payload)) {
|
||||||
|
return throwError(() => new ResponseArgsError(payload));
|
||||||
if (payload.error === true) {
|
}
|
||||||
return throwError(
|
}
|
||||||
() =>
|
return throwError(() => err);
|
||||||
new ResponseArgsError({
|
}),
|
||||||
error: true,
|
mergeMap((response) => {
|
||||||
message: payload.message,
|
if (isResponseArgs(response) && response.error === true) {
|
||||||
invalidProperties: payload.invalidProperties ?? {},
|
return throwError(() => new ResponseArgsError(response));
|
||||||
}),
|
}
|
||||||
);
|
|
||||||
}
|
return [response];
|
||||||
}
|
}),
|
||||||
|
);
|
||||||
return throwError(() => err);
|
|
||||||
}),
|
|
||||||
mergeMap((response) => {
|
|
||||||
if (isResponseArgs(response) && response.error === true) {
|
|
||||||
return throwError(() => new ResponseArgsError(response));
|
|
||||||
}
|
|
||||||
|
|
||||||
return [response];
|
|
||||||
}),
|
|
||||||
);
|
|
||||||
|
|||||||
Reference in New Issue
Block a user