Browse Source

Merge pull request #18787 from abpframework/issue-18774

Fix / Enhancement For Error Handler, Update Documentation
pull/18861/head
Masum ULU 3 years ago
committed by GitHub
parent
commit
b16a6bbf6d
No known key found for this signature in database GPG Key ID: B5690EEEBB952194
  1. 197
      docs/en/UI/Angular/HTTP-Error-Handling.md
  2. 144
      docs/en/UI/Angular/HTTP-Requests.md
  3. 15
      docs/en/docs-nav.json
  4. 6
      npm/ng-packs/packages/core/src/lib/services/rest.service.ts
  5. 21
      npm/ng-packs/packages/theme-shared/src/lib/handlers/error.handler.ts
  6. 4
      npm/ng-packs/packages/theme-shared/src/lib/models/common.ts
  7. 10
      npm/ng-packs/packages/theme-shared/src/lib/providers/error-handlers.provider.ts
  8. 4
      npm/ng-packs/packages/theme-shared/src/lib/theme-shared.module.ts
  9. 3
      npm/ng-packs/packages/theme-shared/src/lib/tokens/http-error.token.ts

197
docs/en/UI/Angular/HTTP-Error-Handling.md

@ -0,0 +1,197 @@
# HTTP Error Handling
When the `RestService` is used, all HTTP errors are reported to the [`HttpErrorReporterService`](./HTTP-Error-Reporter-Service), and then `ErrorHandler`, a service exposed by the `@abp/ng.theme.shared` package automatically handles the errors.
## Custom HTTP Error Handler
### Function Method `Deprecated`
A custom HTTP error handler can be registered to an injection token named `HTTP_ERROR_HANDLER`. If a custom handler function is registered, the `ErrorHandler` executes that function.
See an example:
```ts
// http-error-handler.ts
import { ContentProjectionService, PROJECTION_STRATEGY } from '@abp/ng.core';
import { ToasterService } from '@abp/ng.theme.shared';
import { HttpErrorResponse } from '@angular/common/http';
import { Injector } from '@angular/core';
import { of, EMPTY } from 'rxjs';
import { Error404Component } from './error404/error404.component';
export function handleHttpErrors(injector: Injector, httpError: HttpErrorResponse) {
if (httpError.status === 400) {
const toaster = injector.get(ToasterService);
toaster.error(httpError.error?.error?.message || 'Bad request!', '400');
return EMPTY;
}
if (httpError.status === 404) {
const contentProjection = injector.get(ContentProjectionService);
contentProjection.projectContent(PROJECTION_STRATEGY.AppendComponentToBody(Error404Component));
return EMPTY;
}
return of(httpError);
}
// app.module.ts
import { Error404Component } from './error404/error404.component';
import { handleHttpErrors } from './http-error-handling';
import { HTTP_ERROR_HANDLER, ... } from '@abp/ng.theme.shared';
@NgModule({
// ...
providers: [
// ...
{ provide: HTTP_ERROR_HANDLER, useValue: handleHttpErrors }
],
declarations: [
//...
Error404Component],
})
export class AppModule {}
```
In the example above:
- Created a function named `handleHttpErrors` and defined as value of the `HTTP_ERROR_HANDLER` provider in app.module. After this, the function executes when an HTTP error occurs.
- 400 bad request errors is handled. When a 400 error occurs.
- Since `of(httpError)` is returned at bottom of the `handleHttpErrors`, the `ErrorHandler` will handle the HTTP errors except 400 and 404 errors.
**Note 1:** If you put `return EMPTY` to next line of handling an error, default error handling will not work for that error. [EMPTY](https://rxjs.dev/api/index/const/EMPTY) can be imported from `rxjs`.
```ts
export function handleHttpErrors(
injector: Injector,
httpError: HttpErrorResponse
) {
if (httpError.status === 403) {
// handle 403 errors here
return EMPTY; // put return EMPTY to skip default error handling
}
}
```
**Note 2:** If you put `return of(httpError)`, default error handling will work.
- `of` is a function. It can be imported from `rxjs`.
- `httpError` is the second parameter of the error handler function which is registered to the `HTTP_ERROR_HANDLER` provider. Type of the `httpError` is `HttpErrorResponse`.
```ts
import { of } from "rxjs";
export function handleHttpErrors(
injector: Injector,
httpError: HttpErrorResponse
) {
if (httpError.status === 500) {
// handle 500 errors here
}
// you can return the of(httpError) at bottom of the function to run the default handler of ABP for HTTP errors that you didn't handle above.
return of(httpError);
}
```
### Service Method
You can provide **more than one handler** with services, a custom HTTP error handler service can be registered with injection token named **`CUSTOM_ERROR_HANDLERS`**. ABP has some default [error handlers](https://github.com/abpframework/abp/blob/dev/npm/ng-packs/packages/theme-shared/src/lib/providers/error-handlers.provider.ts).
### How To Add New Handler Service
ABP error handler services are implements the interface of **CustomHttpErrorHandlerService**.
**Interface of `CUSTOM_ERROR_HANDLERS`**
```ts
interface CustomHttpErrorHandlerService {
readonly priority: number;
canHandle(error: unknown): boolean;
execute(): void;
}
```
- **`priority`** ABP sorts the services according to the number of the priority variable. Higher priority will be checked first.
- **`canHandle`** Check if the service can handle the error. Returns boolean.
- **`execute`** If the service can handle the error, then run the execute method.
**In Summary**
- Services are sorted by their priority number.
- Start from highest priority service and run canHandle() method. Pick the service if can handle the error, if not check next service.
- If the service found, run the execute method of a service. Done.
See an example:
```ts
// custom-error-handler.service.ts
import { inject, Injectable } from "@angular/core";
import { HttpErrorResponse } from "@angular/common/http";
import { CustomHttpErrorHandlerService } from "@abp/ng.theme.shared";
import { CUSTOM_HTTP_ERROR_HANDLER_PRIORITY } from "@abp/ng.theme.shared";
import { ToasterService } from "@abp/ng.theme.shared";
@Injectable({ providedIn: "root" })
export class MyCustomErrorHandlerService
implements CustomHttpErrorHandlerService
{
// You can write any number here, ex: 9999
readonly priority = CUSTOM_HTTP_ERROR_HANDLER_PRIORITY.veryHigh;
protected readonly toaster = inject(ToasterService);
private error: HttpErrorResponse | undefined = undefined;
// What kind of error should be handled by this service? You can decide it in this method. If error is suitable to your case then return true; otherwise return false.
canHandle(error: unknown): boolean {
if (error instanceof HttpErrorResponse && error.status === 400) {
this.error = error;
return true;
}
return false;
}
// If this service is picked from ErrorHandler, this execute method will be called.
execute() {
this.toaster.error(
this.error.error?.error?.message || "Bad request!",
"400"
);
}
}
```
```ts
// app.module.ts
import { CUSTOM_ERROR_HANDLERS, ... } from '@abp/ng.theme.shared';
import { MyCustomErrorHandlerService } from './custom-error-handler.service';
@NgModule({
// ...
providers: [
// ...
{
provide: CUSTOM_ERROR_HANDLERS,
useExisting: MyCustomErrorHandlerService,
multi: true,
}
]
})
export class AppModule {}
```
In the example above:
- Created a service named `MyCustomErrorHandlerService`, and provided via `useExisting` key because we dont want another instance of it. And set `multi` key to true because ABP default error handlers are also provided with **CUSTOM_ERROR_HANDLERS** injection token.
- 400 errors are handled from custom `MyCustomErrorHandlerService`. When a 400 error occurs, backend error message will be displayed as shown below:
![custom-error-handler-toaster-message](images/custom-error-handler-toaster-message.jpg)
### Notes
- If your service cannot handle the error. Then ABP will check the next Error Service.
- If none of the service handle the error. Then basic confirmation message about the error will be shown to the user.
- You can provide more than one service, with CUSTOM_ERROR_HANDLER injection token.
- If you want your custom service to be evaluated (checked) earlier, set the priority variable high.

144
docs/en/UI/Angular/HTTP-Requests.md

@ -1,7 +1,5 @@
# How to Make HTTP Requests # How to Make HTTP Requests
## About HttpClient ## About HttpClient
Angular has the amazing [HttpClient](https://angular.io/guide/http) for communication with backend services. It is a layer on top and a simplified representation of [XMLHttpRequest Web API](https://developer.mozilla.org/en-US/docs/Web/API/XMLHttpRequest). It also is the recommended agent by Angular for any HTTP request. There is nothing wrong with using the `HttpClient` in your ABP project. Angular has the amazing [HttpClient](https://angular.io/guide/http) for communication with backend services. It is a layer on top and a simplified representation of [XMLHttpRequest Web API](https://developer.mozilla.org/en-US/docs/Web/API/XMLHttpRequest). It also is the recommended agent by Angular for any HTTP request. There is nothing wrong with using the `HttpClient` in your ABP project.
@ -23,14 +21,10 @@ Although clear and flexible, handling errors this way is repetitive work, even w
An `HttpInterceptor` is able to catch `HttpErrorResponse` and can be used for a centralized error handling. Nevertheless, cases where default error handler, therefore the interceptor, must be disabled require additional work and comprehension of Angular internals. Check [this issue](https://github.com/angular/angular/issues/20203) for details. An `HttpInterceptor` is able to catch `HttpErrorResponse` and can be used for a centralized error handling. Nevertheless, cases where default error handler, therefore the interceptor, must be disabled require additional work and comprehension of Angular internals. Check [this issue](https://github.com/angular/angular/issues/20203) for details.
## RestService ## RestService
ABP core module has a utility service for HTTP requests: `RestService`. Unless explicitly configured otherwise, it catches HTTP errors and dispatches a `RestOccurError` action. This action is then captured by the `ErrorHandler` introduced by the `ThemeSharedModule`. Since you should already import this module in your app, when the `RestService` is used, all HTTP errors get automatically handled by default. ABP core module has a utility service for HTTP requests: `RestService`. Unless explicitly configured otherwise, it catches HTTP errors and dispatches a `RestOccurError` action. This action is then captured by the `ErrorHandler` introduced by the `ThemeSharedModule`. Since you should already import this module in your app, when the `RestService` is used, all HTTP errors get automatically handled by default.
### Getting Started with RestService ### Getting Started with RestService
In order to use the `RestService`, you must inject it in your class as a dependency. In order to use the `RestService`, you must inject it in your class as a dependency.
@ -48,11 +42,9 @@ class DemoService {
You do not have to provide the `RestService` at module or component/directive level, because it is already **provided in root**. You do not have to provide the `RestService` at module or component/directive level, because it is already **provided in root**.
### How to Make a Request with RestService ### How to Make a Request with RestService
You can use the `request` method of the `RestService` is for HTTP requests. Here is an example: You can use the `request` method of the `RestService` is for HTTP requests. Here is an example:
```js ```js
getFoo(id: number) { getFoo(id: number) {
@ -65,8 +57,6 @@ getFoo(id: number) {
} }
``` ```
The `request` method always returns an `Observable<T>`. Therefore you can do the following wherever you use `getFoo` method: The `request` method always returns an `Observable<T>`. Therefore you can do the following wherever you use `getFoo` method:
```js ```js
@ -79,12 +69,8 @@ doSomethingWithFoo(id: number) {
} }
``` ```
**You do not have to worry about unsubscription.** The `RestService` uses `HttpClient` behind the scenes, so every observable it returns is a finite observable, i.e. it closes subscriptions automatically upon success or error. **You do not have to worry about unsubscription.** The `RestService` uses `HttpClient` behind the scenes, so every observable it returns is a finite observable, i.e. it closes subscriptions automatically upon success or error.
As you see, `request` method gets a request options object with `Rest.Request<T>` type. This generic type expects the interface of the request body. You may pass `null` when there is no body, like in a `GET` or a `DELETE` request. Here is an example where there is one: As you see, `request` method gets a request options object with `Rest.Request<T>` type. This generic type expects the interface of the request body. You may pass `null` when there is no body, like in a `GET` or a `DELETE` request. Here is an example where there is one:
```js ```js
@ -99,11 +85,7 @@ postFoo(body: Foo) {
} }
``` ```
You may [check here](https://github.com/abpframework/abp/blob/dev/npm/ng-packs/packages/core/src/lib/models/rest.ts#L23) for complete `Rest.Request<T>` type, which has only a few changes compared to [HttpRequest](https://angular.io/api/common/http/HttpRequest) class in Angular.
You may [check here](https://github.com/abpframework/abp/blob/dev/npm/ng-packs/packages/core/src/lib/models/rest.ts#L23) for complete `Rest.Request<T>` type, which has only a few changes compared to [HttpRequest](https://angular.io/api/common/http/HttpRequest) class in Angular.
### How to Disable Default Error Handler of RestService ### How to Disable Default Error Handler of RestService
@ -120,8 +102,6 @@ deleteFoo(id: number) {
} }
``` ```
`skipHandleError` config option, when set to `true`, disables the error handler and the returned observable starts throwing an error that you can catch in your subscription. `skipHandleError` config option, when set to `true`, disables the error handler and the returned observable starts throwing an error that you can catch in your subscription.
```js ```js
@ -137,14 +117,10 @@ removeFooFromList(id: number) {
} }
``` ```
### How to Get a Specific API Endpoint From Application Config ### How to Get a Specific API Endpoint From Application Config
Another nice config option that `request` method receives is `apiName` (available as of v2.4), which can be used to get a specific module endpoint from application configuration. Another nice config option that `request` method receives is `apiName` (available as of v2.4), which can be used to get a specific module endpoint from application configuration.
```js ```js
putFoo(body: Foo, id: string) { putFoo(body: Foo, id: string) {
const request: Rest.Request<Foo> = { const request: Rest.Request<Foo> = {
@ -157,8 +133,6 @@ putFoo(body: Foo, id: string) {
} }
``` ```
`putFoo` above will request `https://localhost:44305/api/some/path/to/foo/{id}` as long as the environment variables are as follows: `putFoo` above will request `https://localhost:44305/api/some/path/to/foo/{id}` as long as the environment variables are as follows:
```js ```js
@ -167,19 +141,17 @@ putFoo(body: Foo, id: string) {
export const environment = { export const environment = {
apis: { apis: {
default: { default: {
url: 'https://localhost:44305', url: "https://localhost:44305",
}, },
foo: { foo: {
url: 'https://localhost:44305/api/some/path/to/foo', url: "https://localhost:44305/api/some/path/to/foo",
}, },
}, },
/* rest of the environment variables here */ /* rest of the environment variables here */
} };
``` ```
### How to Observe Response Object or HTTP Events Instead of Body ### How to Observe Response Object or HTTP Events Instead of Body
`RestService` assumes you are generally interested in the body of a response and, by default, sets `observe` property as `'body'`. However, there may be times you are rather interested in something else, such as a custom proprietary header. For that, the `request` method receives `observe` property in its config object. `RestService` assumes you are generally interested in the body of a response and, by default, sets `observe` property as `'body'`. However, there may be times you are rather interested in something else, such as a custom proprietary header. For that, the `request` method receives `observe` property in its config object.
@ -202,104 +174,6 @@ getSomeCustomHeaderValue() {
You may find `Rest.Observe` enum [here](https://github.com/abpframework/abp/blob/dev/npm/ng-packs/packages/core/src/lib/models/rest.ts#L10). You may find `Rest.Observe` enum [here](https://github.com/abpframework/abp/blob/dev/npm/ng-packs/packages/core/src/lib/models/rest.ts#L10).
## HTTP Error Handling
When the `RestService` is used, all HTTP errors are reported to the [`HttpErrorReporterService`](./HTTP-Error-Reporter-Service), and then `ErrorHandler`, a service exposed by the `@abp/ng.theme.shared` package automatically handles the errors.
### Custom HTTP Error Handler
A custom HTTP error handler can be registered to an injection token named `HTTP_ERROR_HANDLER`. If a custom handler function is registered, the `ErrorHandler` executes that function.
See an example:
```js
// http-error-handler.ts
import { ContentProjectionService, PROJECTION_STRATEGY } from '@abp/ng.core';
import { ToasterService } from '@abp/ng.theme.shared';
import { HttpErrorResponse } from '@angular/common/http';
import { Injector } from '@angular/core';
import { throwError } from 'rxjs';
import { Error404Component } from './error404/error404.component';
export function handleHttpErrors(injector: Injector, httpError: HttpErrorResponse) {
if (httpError.status === 400) {
const toaster = injector.get(ToasterService);
toaster.error(httpError.error?.error?.message || 'Bad request!', '400');
return;
}
if (httpError.status === 404) {
const contentProjection = injector.get(ContentProjectionService);
contentProjection.projectContent(PROJECTION_STRATEGY.AppendComponentToBody(Error404Component));
return;
}
return throwError(httpError);
}
// app.module.ts
import { Error404Component } from './error404/error404.component';
import { handleHttpErrors } from './http-error-handling';
import { HTTP_ERROR_HANDLER, ... } from '@abp/ng.theme.shared';
@NgModule({
// ...
providers: [
// ...
{ provide: HTTP_ERROR_HANDLER, useValue: handleHttpErrors }
],
declarations: [
//...
Error404Component],
})
export class AppModule {}
```
In the example above:
- Created a function named `handleHttpErrors` and defined as value of the `HTTP_ERROR_HANDLER` provider in app.module. After this, the function executes when an HTTP error occurs.
- 400 bad request errors is handled. When a 400 error occurs, backend error message will be displayed as shown below:
![custom-error-handler-toaster-message](images/custom-error-handler-toaster-message.jpg)
- 404 not found errors is handled. When a 404 error occurs, `Error404Component` will be appended to the `<body>` as shown below:
![custom-error-handler-404-component](images/custom-error-handler-404-component.jpg)
- Since `throwError(httpError)` is returned at bottom of the `handleHttpErrors`, the `ErrorHandler` will handle the HTTP errors except 400 and 404 errors.
**Note 1:** If you put `return` to next line of handling an error, default error handling will not work for that error.
```js
export function handleHttpErrors(injector: Injector, httpError: HttpErrorResponse) {
if (httpError.status === 403) {
// handle 403 errors here
return; // put return to skip default error handling
}
}
```
**Note 2:** If you put `return throwError(httpError)`, default error handling will work.
- `throwError` is a function. It can be imported from `rxjs`.
- `httpError` is the second parameter of the error handler function which is registered to the `HTTP_ERROR_HANDLER` provider. Type of the `httpError` is `HttpErrorResponse`.
```js
import { throwError } from 'rxjs';
export function handleHttpErrors(injector: Injector, httpError: HttpErrorResponse) {
if (httpError.status === 500) {
// handle 500 errors here
return;
}
// you can return the throwError(httpError) at bottom of the function to run the default handler of ABP for HTTP errors that you didn't handle above.
return throwError(httpError)
}
```
### How to Skip HTTP interceptors and ABP headers ### How to Skip HTTP interceptors and ABP headers
The ABP Framework adds several HTTP headers to the HttpClient, such as the "Auth token" or "tenant Id". The ABP Framework adds several HTTP headers to the HttpClient, such as the "Auth token" or "tenant Id".
@ -309,4 +183,8 @@ The ABP Http interceptors check the value of the `IS_EXTERNAL_REQUEST` token. If
The `ExternalHttpClient` extends from `HTTPClient` and sets the `IS_EXTERNAL_REQUEST` context token to true. The `ExternalHttpClient` extends from `HTTPClient` and sets the `IS_EXTERNAL_REQUEST` context token to true.
When you are using `ExternalHttpClient` as HttpClient in your components, it does not add ABP-specific headers. When you are using `ExternalHttpClient` as HttpClient in your components, it does not add ABP-specific headers.
Note: With `IS_EXTERNAL_REQUEST` or without it, ABP loading service works. Note: With `IS_EXTERNAL_REQUEST` or without it, ABP loading service works.
## See Also
- [HTTP Error Handling / Customization](./HTTP-Error-Handling)

15
docs/en/docs-nav.json

@ -1053,7 +1053,16 @@
}, },
{ {
"text": "HTTP Requests", "text": "HTTP Requests",
"path": "UI/Angular/HTTP-Requests.md" "items": [
{
"text": "How to Make HTTP Requests",
"path": "UI/Angular/HTTP-Requests.md"
},
{
"text": "HTTP Error Handling / Customization",
"path": "UI/Angular/HTTP-Error-Handling.md"
}
]
}, },
{ {
"text": "Localization", "text": "Localization",
@ -1173,8 +1182,8 @@
"path": "UI/Angular/Content-Security-Strategy.md" "path": "UI/Angular/Content-Security-Strategy.md"
}, },
{ {
"text":"Abp Window Service", "text": "Abp Window Service",
"path":"UI/Angular/Abp-Window-Service.md" "path": "UI/Angular/Abp-Window-Service.md"
} }
] ]
}, },

6
npm/ng-packs/packages/core/src/lib/services/rest.service.ts

@ -20,7 +20,7 @@ export class RestService {
protected externalHttp: ExternalHttpClient, protected externalHttp: ExternalHttpClient,
protected environment: EnvironmentService, protected environment: EnvironmentService,
protected httpErrorReporter: HttpErrorReporterService, protected httpErrorReporter: HttpErrorReporterService,
) {} ) { }
protected getApiFromStore(apiName: string | undefined): string { protected getApiFromStore(apiName: string | undefined): string {
return this.environment.getApiUrl(apiName); return this.environment.getApiUrl(apiName);
@ -28,7 +28,7 @@ export class RestService {
handleError(err: any): Observable<any> { handleError(err: any): Observable<any> {
this.httpErrorReporter.reportError(err); this.httpErrorReporter.reportError(err);
return throwError(err); return throwError(() => err);
} }
request<T, R>( request<T, R>(
@ -51,7 +51,7 @@ export class RestService {
}), }),
...options, ...options,
} as any) } as any)
.pipe(catchError(err => (skipHandleError ? throwError(err) : this.handleError(err)))); .pipe(catchError(err => (skipHandleError ? throwError(() => err) : this.handleError(err))));
} }
private getHttpClient(isExternal: boolean) { private getHttpClient(isExternal: boolean) {
return isExternal ? this.externalHttp : this.http; return isExternal ? this.externalHttp : this.http;

21
npm/ng-packs/packages/theme-shared/src/lib/handlers/error.handler.ts

@ -1,7 +1,7 @@
import { inject, Injectable, Injector } from '@angular/core'; import { inject, Injectable, Injector } from '@angular/core';
import { HttpErrorResponse } from '@angular/common/http'; import { HttpErrorResponse } from '@angular/common/http';
import { Observable, of, throwError } from 'rxjs'; import { Observable, of } from 'rxjs';
import { catchError, filter, switchMap } from 'rxjs/operators'; import { filter, switchMap } from 'rxjs/operators';
import { HttpErrorReporterService } from '@abp/ng.core'; import { HttpErrorReporterService } from '@abp/ng.core';
@ -22,9 +22,7 @@ export class ErrorHandler {
protected readonly routerErrorHandlerService = inject(RouterErrorHandlerService); protected readonly routerErrorHandlerService = inject(RouterErrorHandlerService);
protected readonly httpErrorConfig = inject(HTTP_ERROR_CONFIG); protected readonly httpErrorConfig = inject(HTTP_ERROR_CONFIG);
protected readonly customErrorHandlers = inject(CUSTOM_ERROR_HANDLERS); protected readonly customErrorHandlers = inject(CUSTOM_ERROR_HANDLERS);
protected readonly defaultHttpErrorHandler = (_, err: HttpErrorResponse) => throwError(() => err); protected readonly httpErrorHandler = inject(HTTP_ERROR_HANDLER, { optional: true });
protected readonly httpErrorHandler =
inject(HTTP_ERROR_HANDLER, { optional: true }) || this.defaultHttpErrorHandler;
constructor(protected injector: Injector) { constructor(protected injector: Injector) {
this.listenToRestError(); this.listenToRestError();
@ -42,10 +40,11 @@ export class ErrorHandler {
} }
protected executeErrorHandler = (error: HttpErrorResponse) => { protected executeErrorHandler = (error: HttpErrorResponse) => {
const errHandler = this.httpErrorHandler(this.injector, error); if (this.httpErrorHandler) {
const isObservable = errHandler instanceof Observable; return this.httpErrorHandler(this.injector, error);
}
return (isObservable ? errHandler : of(null)).pipe(catchError(err => of(err))); return of(error);
}; };
protected sortHttpErrorHandlers( protected sortHttpErrorHandlers(
@ -57,12 +56,12 @@ export class ErrorHandler {
protected handleError(err: unknown) { protected handleError(err: unknown) {
if (this.customErrorHandlers && this.customErrorHandlers.length) { if (this.customErrorHandlers && this.customErrorHandlers.length) {
const canHandleService = this.customErrorHandlers const errorHandlerService = this.customErrorHandlers
.sort(this.sortHttpErrorHandlers) .sort(this.sortHttpErrorHandlers)
.find(service => service.canHandle(err)); .find(service => service.canHandle(err));
if (canHandleService) { if (errorHandlerService) {
canHandleService.execute(); errorHandlerService.execute();
return; return;
} }
} }

4
npm/ng-packs/packages/theme-shared/src/lib/models/common.ts

@ -1,5 +1,5 @@
import { HttpErrorResponse } from '@angular/common/http'; import { HttpErrorResponse } from '@angular/common/http';
import { Type } from '@angular/core'; import { Injector, Type } from '@angular/core';
import { Validation } from '@ngx-validate/core'; import { Validation } from '@ngx-validate/core';
import { Observable } from 'rxjs'; import { Observable } from 'rxjs';
import { ConfirmationIcons } from '../tokens/confirmation-icons.token'; import { ConfirmationIcons } from '../tokens/confirmation-icons.token';
@ -20,7 +20,7 @@ export interface HttpErrorConfig {
hideCloseIcon?: boolean; hideCloseIcon?: boolean;
}; };
} }
export type HttpErrorHandler<T = any> = (httpError: HttpErrorResponse) => Observable<T>; export type HttpErrorHandler<T = any> = (injector: Injector, httpError: HttpErrorResponse) => Observable<T>;
export type LocaleDirection = 'ltr' | 'rtl'; export type LocaleDirection = 'ltr' | 'rtl';
export interface CustomHttpErrorHandlerService { export interface CustomHttpErrorHandlerService {

10
npm/ng-packs/packages/theme-shared/src/lib/providers/error-handlers.provider.ts

@ -5,25 +5,25 @@ import { AbpFormatErrorHandlerService } from '../services/abp-format-error-handl
import { StatusCodeErrorHandlerService } from '../services/status-code-error-handler.service'; import { StatusCodeErrorHandlerService } from '../services/status-code-error-handler.service';
import { UnknownStatusCodeErrorHandlerService } from '../services/unknown-status-code-error-handler.service'; import { UnknownStatusCodeErrorHandlerService } from '../services/unknown-status-code-error-handler.service';
export const ERROR_HANDLERS_PROVIDERS: Provider[] = [ export const DEFAULT_HANDLERS_PROVIDERS: Provider[] = [
{ {
provide: CUSTOM_ERROR_HANDLERS, provide: CUSTOM_ERROR_HANDLERS,
multi: true, multi: true,
useClass: TenantResolveErrorHandlerService, useExisting: TenantResolveErrorHandlerService,
}, },
{ {
provide: CUSTOM_ERROR_HANDLERS, provide: CUSTOM_ERROR_HANDLERS,
multi: true, multi: true,
useClass: AbpFormatErrorHandlerService, useExisting: AbpFormatErrorHandlerService,
}, },
{ {
provide: CUSTOM_ERROR_HANDLERS, provide: CUSTOM_ERROR_HANDLERS,
multi: true, multi: true,
useClass: StatusCodeErrorHandlerService, useExisting: StatusCodeErrorHandlerService,
}, },
{ {
provide: CUSTOM_ERROR_HANDLERS, provide: CUSTOM_ERROR_HANDLERS,
multi: true, multi: true,
useClass: UnknownStatusCodeErrorHandlerService, useExisting: UnknownStatusCodeErrorHandlerService,
}, },
]; ];

4
npm/ng-packs/packages/theme-shared/src/lib/theme-shared.module.ts

@ -29,7 +29,7 @@ import { NgxDatatableListDirective } from './directives/ngx-datatable-list.direc
import { DocumentDirHandlerService } from './handlers/document-dir.handler'; import { DocumentDirHandlerService } from './handlers/document-dir.handler';
import { ErrorHandler } from './handlers/error.handler'; import { ErrorHandler } from './handlers/error.handler';
import { RootParams } from './models/common'; import { RootParams } from './models/common';
import { ERROR_HANDLERS_PROVIDERS, NG_BOOTSTRAP_CONFIG_PROVIDERS } from './providers'; import { DEFAULT_HANDLERS_PROVIDERS, NG_BOOTSTRAP_CONFIG_PROVIDERS } from './providers';
import { THEME_SHARED_ROUTE_PROVIDERS } from './providers/route.provider'; import { THEME_SHARED_ROUTE_PROVIDERS } from './providers/route.provider';
import { THEME_SHARED_APPEND_CONTENT } from './tokens/append-content.token'; import { THEME_SHARED_APPEND_CONTENT } from './tokens/append-content.token';
import { HTTP_ERROR_CONFIG, httpErrorConfigFactory } from './tokens/http-error.token'; import { HTTP_ERROR_CONFIG, httpErrorConfigFactory } from './tokens/http-error.token';
@ -149,7 +149,7 @@ export class ThemeSharedModule {
}, },
}, },
tenantNotFoundProvider, tenantNotFoundProvider,
ERROR_HANDLERS_PROVIDERS, DEFAULT_HANDLERS_PROVIDERS,
], ],
}; };
} }

3
npm/ng-packs/packages/theme-shared/src/lib/tokens/http-error.token.ts

@ -15,6 +15,9 @@ export function httpErrorConfigFactory(config = {} as HttpErrorConfig) {
export const HTTP_ERROR_CONFIG = new InjectionToken<HttpErrorConfig>('HTTP_ERROR_CONFIG'); export const HTTP_ERROR_CONFIG = new InjectionToken<HttpErrorConfig>('HTTP_ERROR_CONFIG');
/**
@deprecated use **`CUSTOM_ERROR_HANDLERS`** injection token instead of this, see more info https://docs.abp.io/en/abp/latest/UI/Angular/HTTP-Requests
*/
export const HTTP_ERROR_HANDLER = new InjectionToken<HttpErrorHandler>('HTTP_ERROR_HANDLER'); export const HTTP_ERROR_HANDLER = new InjectionToken<HttpErrorHandler>('HTTP_ERROR_HANDLER');
export const CUSTOM_ERROR_HANDLERS = new InjectionToken<CustomHttpErrorHandlerService[]>( export const CUSTOM_ERROR_HANDLERS = new InjectionToken<CustomHttpErrorHandlerService[]>(

Loading…
Cancel
Save