mirror of https://github.com/abpframework/abp.git
5 changed files with 163 additions and 100 deletions
@ -0,0 +1,45 @@ |
|||
export const DEFAULT_ERROR_MESSAGES = { |
|||
defaultError: { |
|||
title: 'An error has occurred!', |
|||
details: 'Error detail not sent by server.', |
|||
}, |
|||
defaultError401: { |
|||
title: 'You are not authenticated!', |
|||
details: 'You should be authenticated (sign in) in order to perform this operation.', |
|||
}, |
|||
defaultError403: { |
|||
title: 'You are not authorized!', |
|||
details: 'You are not allowed to perform this operation.', |
|||
}, |
|||
defaultError404: { |
|||
title: 'Resource not found!', |
|||
details: 'The resource requested could not found on the server.', |
|||
}, |
|||
defaultError500: { |
|||
title: 'Internal server error', |
|||
details: 'Error detail not sent by server.', |
|||
}, |
|||
}; |
|||
|
|||
export const DEFAULT_ERROR_LOCALIZATIONS = { |
|||
defaultError: { |
|||
title: 'AbpUi::DefaultErrorMessage', |
|||
details: 'AbpUi::DefaultErrorMessageDetail', |
|||
}, |
|||
defaultError401: { |
|||
title: 'AbpUi::DefaultErrorMessage401', |
|||
details: 'AbpUi::DefaultErrorMessage401Detail', |
|||
}, |
|||
defaultError403: { |
|||
title: 'AbpUi::DefaultErrorMessage403', |
|||
details: 'AbpUi::DefaultErrorMessage403Detail', |
|||
}, |
|||
defaultError404: { |
|||
title: 'AbpUi::DefaultErrorMessage404', |
|||
details: 'AbpUi::DefaultErrorMessage404Detail', |
|||
}, |
|||
defaultError500: { |
|||
title: 'AbpUi::500Message', |
|||
details: 'AbpUi::DefaultErrorMessage', |
|||
}, |
|||
}; |
|||
@ -0,0 +1,18 @@ |
|||
import { inject, Injectable } from '@angular/core'; |
|||
import { ErrorScreenErrorCodes } from '../models/common'; |
|||
import { HTTP_ERROR_CONFIG } from '@abp/ng.theme.shared'; |
|||
|
|||
@Injectable({ |
|||
providedIn: 'root', |
|||
}) |
|||
export class CanCreateCustomErrorService { |
|||
private httpErrorConfig = inject(HTTP_ERROR_CONFIG); |
|||
|
|||
execute(status: ErrorScreenErrorCodes): boolean { |
|||
return !!( |
|||
this.httpErrorConfig?.errorScreen?.component && |
|||
this.httpErrorConfig?.errorScreen?.forWhichErrors && |
|||
this.httpErrorConfig?.errorScreen?.forWhichErrors.indexOf(status) > -1 |
|||
); |
|||
} |
|||
} |
|||
@ -0,0 +1,89 @@ |
|||
import { |
|||
ApplicationRef, |
|||
ComponentFactoryResolver, |
|||
ComponentRef, |
|||
EmbeddedViewRef, |
|||
inject, |
|||
Injectable, |
|||
Injector, |
|||
RendererFactory2, |
|||
} from '@angular/core'; |
|||
import { |
|||
ErrorScreenErrorCodes, |
|||
HTTP_ERROR_CONFIG, |
|||
HttpErrorWrapperComponent, |
|||
} from '@abp/ng.theme.shared'; |
|||
import { Subject } from 'rxjs'; |
|||
import { ResolveEnd } from '@angular/router'; |
|||
import { filter } from 'rxjs/operators'; |
|||
import { RouterEvents } from '@abp/ng.core'; |
|||
import { CanCreateCustomErrorService } from './can-create-custom-error.service'; |
|||
|
|||
@Injectable({ providedIn: 'root' }) |
|||
export class CreateErrorComponentService { |
|||
protected rendererFactory = inject(RendererFactory2); |
|||
protected cfRes = inject(ComponentFactoryResolver); |
|||
private routerEvents = inject(RouterEvents); |
|||
private injector = inject(Injector); |
|||
private canCreateCustomErrorService = inject(CanCreateCustomErrorService); |
|||
private httpErrorConfig = inject(HTTP_ERROR_CONFIG); |
|||
|
|||
componentRef: ComponentRef<HttpErrorWrapperComponent> | null = null; |
|||
|
|||
protected getErrorHostElement() { |
|||
return document.body; |
|||
} |
|||
|
|||
constructor() { |
|||
this.listenToRouterDataResolved(); |
|||
} |
|||
protected listenToRouterDataResolved() { |
|||
this.routerEvents |
|||
.getEvents(ResolveEnd) |
|||
.pipe(filter(() => !!this.componentRef)) |
|||
.subscribe(() => { |
|||
this.componentRef?.destroy(); |
|||
this.componentRef = null; |
|||
}); |
|||
} |
|||
|
|||
private isCloseIconHidden() { |
|||
return !!this.httpErrorConfig.errorScreen?.hideCloseIcon; |
|||
} |
|||
execute(instance: Partial<HttpErrorWrapperComponent>) { |
|||
const renderer = this.rendererFactory.createRenderer(null, null); |
|||
const hostElement = this.getErrorHostElement(); |
|||
const host = renderer.selectRootElement(hostElement, true); |
|||
|
|||
this.componentRef = this.cfRes |
|||
.resolveComponentFactory(HttpErrorWrapperComponent) |
|||
.create(this.injector); |
|||
|
|||
for (const key in instance) { |
|||
/* istanbul ignore else */ |
|||
if (Object.prototype.hasOwnProperty.call(this.componentRef.instance, key)) { |
|||
(this.componentRef.instance as any)[key] = (instance as any)[key]; |
|||
} |
|||
} |
|||
|
|||
this.componentRef.instance.hideCloseIcon = this.isCloseIconHidden(); |
|||
const appRef = this.injector.get(ApplicationRef); |
|||
|
|||
if (this.canCreateCustomErrorService.execute(instance.status as ErrorScreenErrorCodes)) { |
|||
this.componentRef.instance.cfRes = this.cfRes; |
|||
this.componentRef.instance.appRef = appRef; |
|||
this.componentRef.instance.injector = this.injector; |
|||
this.componentRef.instance.customComponent = this.httpErrorConfig.errorScreen?.component; |
|||
} |
|||
|
|||
appRef.attachView(this.componentRef.hostView); |
|||
renderer.appendChild(host, (this.componentRef.hostView as EmbeddedViewRef<any>).rootNodes[0]); |
|||
|
|||
const destroy$ = new Subject<void>(); |
|||
this.componentRef.instance.destroy$ = destroy$; |
|||
destroy$.subscribe(() => { |
|||
this.componentRef?.destroy(); |
|||
this.componentRef = null; |
|||
}); |
|||
} |
|||
} |
|||
Loading…
Reference in new issue