Browse Source

Merge pull request #3652 from abpframework/feat/skip-error-handling

Added an property named skipHandledErrorCodes to forRoot options of ThemeShared
pull/3665/head
Levent Arman Özak 7 years ago
committed by GitHub
parent
commit
9212f2a7f8
No known key found for this signature in database GPG Key ID: 4AEE18F83AFDEB23
  1. 217
      npm/ng-packs/packages/theme-shared/src/lib/handlers/error.handler.ts
  2. 7
      npm/ng-packs/packages/theme-shared/src/lib/models/common.ts
  3. 1
      npm/ng-packs/packages/theme-shared/src/lib/tokens/http-error.token.ts

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

@ -19,6 +19,7 @@ import { HttpErrorWrapperComponent } from '../components/http-error-wrapper/http
import { HttpErrorConfig, ErrorScreenErrorCodes } from '../models/common'; import { HttpErrorConfig, ErrorScreenErrorCodes } from '../models/common';
import { Confirmation } from '../models/confirmation'; import { Confirmation } from '../models/confirmation';
import { ConfirmationService } from '../services/confirmation.service'; import { ConfirmationService } from '../services/confirmation.service';
import { filter, tap } from 'rxjs/operators';
export const DEFAULT_ERROR_MESSAGES = { export const DEFAULT_ERROR_MESSAGES = {
defaultError: { defaultError: {
@ -57,108 +58,122 @@ export class ErrorHandler {
private injector: Injector, private injector: Injector,
@Inject('HTTP_ERROR_CONFIG') private httpErrorConfig: HttpErrorConfig, @Inject('HTTP_ERROR_CONFIG') private httpErrorConfig: HttpErrorConfig,
) { ) {
this.httpErrorConfig.skipHandledErrorCodes = this.httpErrorConfig.skipHandledErrorCodes || [];
this.listenToRestError();
this.listenToRouterError();
this.listenToRouterDataResolved();
}
private listenToRouterError() {
this.actions this.actions
.pipe(ofActionSuccessful(RestOccurError, RouterError, RouterDataResolved)) .pipe(ofActionSuccessful(RouterError), filter(this.filterRouteErrors), tap(console.warn))
.subscribe(res => { .subscribe(() => this.show404Page());
if (res instanceof RestOccurError) { }
const { payload: err = {} as HttpErrorResponse | any } = res;
const body = snq(
() => (err as HttpErrorResponse).error.error,
DEFAULT_ERROR_MESSAGES.defaultError.title,
);
if (err instanceof HttpErrorResponse && err.headers.get('_AbpErrorFormat')) { private listenToRouterDataResolved() {
const confirmation$ = this.showError(null, null, body); this.actions
.pipe(
ofActionSuccessful(RouterDataResolved),
filter(() => !!this.componentRef),
)
.subscribe(() => {
this.componentRef.destroy();
this.componentRef = null;
});
}
if (err.status === 401) { private listenToRestError() {
confirmation$.subscribe(() => { this.actions
this.navigateToLogin(); .pipe(ofActionSuccessful(RestOccurError), filter(this.filterRestErrors))
.subscribe(({ payload: { err = {} as HttpErrorResponse } }) => {
const body = snq(
() => (err as HttpErrorResponse).error.error,
DEFAULT_ERROR_MESSAGES.defaultError.title,
);
if (err instanceof HttpErrorResponse && err.headers.get('_AbpErrorFormat')) {
const confirmation$ = this.showError(null, null, body);
if (err.status === 401) {
confirmation$.subscribe(() => {
this.navigateToLogin();
});
}
} else {
switch ((err as HttpErrorResponse).status) {
case 401:
this.canCreateCustomError(401)
? this.show401Page()
: this.showError(
{
key: 'AbpAccount::DefaultErrorMessage401',
defaultValue: DEFAULT_ERROR_MESSAGES.defaultError401.title,
},
{
key: 'AbpAccount::DefaultErrorMessage401Detail',
defaultValue: DEFAULT_ERROR_MESSAGES.defaultError401.details,
},
).subscribe(() => this.navigateToLogin());
break;
case 403:
this.createErrorComponent({
title: {
key: 'AbpAccount::DefaultErrorMessage403',
defaultValue: DEFAULT_ERROR_MESSAGES.defaultError403.title,
},
details: {
key: 'AbpAccount::DefaultErrorMessage403Detail',
defaultValue: DEFAULT_ERROR_MESSAGES.defaultError403.details,
},
status: 403,
}); });
} break;
} else { case 404:
switch ((err as HttpErrorResponse).status) { this.canCreateCustomError(404)
case 401: ? this.show404Page()
this.canCreateCustomError(401) : this.showError(
? this.show401Page() {
: this.showError( key: 'AbpAccount::DefaultErrorMessage404',
{ defaultValue: DEFAULT_ERROR_MESSAGES.defaultError404.details,
key: 'AbpAccount::DefaultErrorMessage401', },
defaultValue: DEFAULT_ERROR_MESSAGES.defaultError401.title, {
}, key: 'AbpAccount::DefaultErrorMessage404Detail',
{ defaultValue: DEFAULT_ERROR_MESSAGES.defaultError404.title,
key: 'AbpAccount::DefaultErrorMessage401Detail', },
defaultValue: DEFAULT_ERROR_MESSAGES.defaultError401.details, );
}, break;
).subscribe(() => this.navigateToLogin()); case 500:
break; this.createErrorComponent({
case 403: title: {
this.createErrorComponent({ key: 'AbpAccount::500Message',
title: { defaultValue: DEFAULT_ERROR_MESSAGES.defaultError500.title,
key: 'AbpAccount::DefaultErrorMessage403', },
defaultValue: DEFAULT_ERROR_MESSAGES.defaultError403.title, details: {
}, key: 'AbpAccount::InternalServerErrorMessage',
details: { defaultValue: DEFAULT_ERROR_MESSAGES.defaultError500.details,
key: 'AbpAccount::DefaultErrorMessage403Detail', },
defaultValue: DEFAULT_ERROR_MESSAGES.defaultError403.details, status: 500,
}, });
status: 403, break;
}); case 0:
break; if ((err as HttpErrorResponse).statusText === 'Unknown Error') {
case 404:
this.canCreateCustomError(404)
? this.show404Page()
: this.showError(
{
key: 'AbpAccount::DefaultErrorMessage404',
defaultValue: DEFAULT_ERROR_MESSAGES.defaultError404.details,
},
{
key: 'AbpAccount::DefaultErrorMessage404Detail',
defaultValue: DEFAULT_ERROR_MESSAGES.defaultError404.title,
},
);
break;
case 500:
this.createErrorComponent({ this.createErrorComponent({
title: { title: {
key: 'AbpAccount::500Message', key: 'AbpAccount::DefaultErrorMessage',
defaultValue: DEFAULT_ERROR_MESSAGES.defaultError500.title, defaultValue: DEFAULT_ERROR_MESSAGES.defaultError.title,
}, },
details: { details: err.message,
key: 'AbpAccount::InternalServerErrorMessage', isHomeShow: false,
defaultValue: DEFAULT_ERROR_MESSAGES.defaultError500.details,
},
status: 500,
}); });
break; }
case 0: break;
if ((err as HttpErrorResponse).statusText === 'Unknown Error') { default:
this.createErrorComponent({ this.showError(
title: { DEFAULT_ERROR_MESSAGES.defaultError.details,
key: 'AbpAccount::DefaultErrorMessage', DEFAULT_ERROR_MESSAGES.defaultError.title,
defaultValue: DEFAULT_ERROR_MESSAGES.defaultError.title, );
}, break;
details: err.message,
isHomeShow: false,
});
}
break;
default:
this.showError(
DEFAULT_ERROR_MESSAGES.defaultError.details,
DEFAULT_ERROR_MESSAGES.defaultError.title,
);
break;
}
} }
} else if (
res instanceof RouterError &&
snq(() => res.event.error.indexOf('Cannot match') > -1, false)
) {
this.show404Page();
} else if (res instanceof RouterDataResolved && this.componentRef) {
this.componentRef.destroy();
this.componentRef = null;
} }
}); });
} }
@ -254,4 +269,20 @@ export class ErrorHandler {
this.httpErrorConfig.errorScreen.forWhichErrors.indexOf(status) > -1, this.httpErrorConfig.errorScreen.forWhichErrors.indexOf(status) > -1,
); );
} }
private filterRestErrors = (instance: RestOccurError): boolean => {
const {
payload: { err: { status } = {} as HttpErrorResponse },
} = instance;
if (!status) return false;
return this.httpErrorConfig.skipHandledErrorCodes.findIndex(code => code === status) < 0;
};
private filterRouteErrors = (instance: RouterError<any>): boolean => {
return (
snq(() => instance.event.error.indexOf('Cannot match') > -1) &&
this.httpErrorConfig.skipHandledErrorCodes.findIndex(code => code === 404) < 0
);
};
} }

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

@ -7,13 +7,10 @@ export interface RootParams {
export type ErrorScreenErrorCodes = 401 | 403 | 404 | 500; export type ErrorScreenErrorCodes = 401 | 403 | 404 | 500;
export interface HttpErrorConfig { export interface HttpErrorConfig {
skipHandledErrorCodes?: ErrorScreenErrorCodes[] | number[];
errorScreen?: { errorScreen?: {
component: Type<any>; component: Type<any>;
forWhichErrors?: forWhichErrors?: ErrorScreenErrorCodes[];
| [ErrorScreenErrorCodes]
| [ErrorScreenErrorCodes, ErrorScreenErrorCodes]
| [ErrorScreenErrorCodes, ErrorScreenErrorCodes, ErrorScreenErrorCodes]
| [ErrorScreenErrorCodes, ErrorScreenErrorCodes, ErrorScreenErrorCodes, ErrorScreenErrorCodes];
hideCloseIcon?: boolean; hideCloseIcon?: boolean;
}; };
} }

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

@ -7,6 +7,7 @@ export function httpErrorConfigFactory(config = {} as HttpErrorConfig) {
} }
return { return {
skipHandledErrorCodes: [],
errorScreen: {}, errorScreen: {},
...config, ...config,
} as HttpErrorConfig; } as HttpErrorConfig;

Loading…
Cancel
Save