mirror of
https://dev.azure.com/hugendubel/ISA/_git/ISA-Frontend
synced 2025-12-28 22:42:11 +01:00
feat(common/data-access): enhance error handling with ResponseArgsError operator
Add catchResponseArgsErrorPipe operator to transform HTTP errors into structured ResponseArgsError instances. This provides consistent error handling across data access services by automatically converting HttpErrorResponse objects with ResponseArgs payloads into typed ResponseArgsError instances. Changes include: - New catchResponseArgsErrorPipe operator for standardized error transformation - Enhanced DataAccessError with proper prototype chain setup - Integration in CatalougeSearchService for loyalty items search - Export operator from common data-access module This improves error consistency and debugging capabilities across the application by ensuring all API errors follow the same structure and typing. Refs: #5258
This commit is contained in:
@@ -1,7 +1,13 @@
|
||||
import { inject, Injectable } from '@angular/core';
|
||||
import { SearchService } from '@generated/swagger/cat-search-api';
|
||||
import {
|
||||
ListResponseArgsOfItemDTO,
|
||||
SearchService,
|
||||
} from '@generated/swagger/cat-search-api';
|
||||
import { firstValueFrom, map, Observable } from 'rxjs';
|
||||
import { takeUntilAborted } from '@isa/common/data-access';
|
||||
import {
|
||||
catchResponseArgsErrorPipe,
|
||||
takeUntilAborted,
|
||||
} from '@isa/common/data-access';
|
||||
import { Item } from '../models';
|
||||
import {
|
||||
SearchByTermInput,
|
||||
@@ -70,7 +76,10 @@ export class CatalougeSearchService {
|
||||
skip,
|
||||
take,
|
||||
})
|
||||
.pipe(takeUntilAborted(abortSignal));
|
||||
.pipe(
|
||||
takeUntilAborted(abortSignal),
|
||||
catchResponseArgsErrorPipe<ListResponseArgsOfItemDTO>(),
|
||||
);
|
||||
|
||||
const res = await firstValueFrom(req$);
|
||||
|
||||
|
||||
@@ -44,5 +44,7 @@ export class DataAccessError<TCode extends string, TData = void> extends Error {
|
||||
public readonly data: TData,
|
||||
) {
|
||||
super(message);
|
||||
Object.setPrototypeOf(this, new.target.prototype);
|
||||
this.name = new.target.name;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,45 @@
|
||||
import { catchError } from 'rxjs/operators';
|
||||
import { OperatorFunction, throwError } from 'rxjs';
|
||||
import { ResponseArgsError } from '../errors';
|
||||
import { HttpErrorResponse } from '@angular/common/http';
|
||||
import { ResponseArgs } from '../models';
|
||||
|
||||
/**
|
||||
*
|
||||
* Operator that catches errors from an observable stream and transforms them into
|
||||
*
|
||||
* `ResponseArgsError` instances when applicable.
|
||||
* This operator is useful for handling HTTP errors that return a structured
|
||||
* response conforming to the `ResponseArgs` interface.
|
||||
*
|
||||
* If the error is already a `ResponseArgsError`, it is re-thrown as is.
|
||||
* If the error is an `HttpErrorResponse` with a valid `ResponseArgs` payload,
|
||||
* it creates and throws a new `ResponseArgsError`.
|
||||
* For all other error types, it re-throws the original error.
|
||||
*
|
||||
*/
|
||||
export const catchResponseArgsErrorPipe = <T>(): OperatorFunction<T, T> =>
|
||||
catchError((err: unknown) => {
|
||||
if (err instanceof ResponseArgsError) {
|
||||
return throwError(() => err);
|
||||
}
|
||||
|
||||
if (err instanceof HttpErrorResponse && err.error) {
|
||||
const payload = err.error as Partial<ResponseArgs<unknown>>;
|
||||
|
||||
if (payload.error === true) {
|
||||
return throwError(
|
||||
() =>
|
||||
new ResponseArgsError({
|
||||
error: true,
|
||||
message: payload.message,
|
||||
invalidProperties: payload.invalidProperties ?? {},
|
||||
}),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
return throwError(() =>
|
||||
err instanceof Error ? err : new Error(String(err)),
|
||||
);
|
||||
});
|
||||
@@ -1,2 +1,3 @@
|
||||
export * from './take-until-aborted';
|
||||
export * from './take-unitl-keydown';
|
||||
export * from './catch-response-args-error';
|
||||
|
||||
Reference in New Issue
Block a user