fix: static-page loadByKey/loadByPath had no error handler, infinite spinner on failure
Some checks failed
Architecture Governance / architecture (push) Has been cancelled

resolveByKey/resolveByRoute subscribed with only a next callback -
a resolver failure left loading=true forever with no error branch to
recover from. Added an error signal, error subscribe handler, and a
distinct error state UI (separate from the existing 404 not-found
state) with a way back home.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
sdarbinyan
2026-08-13 08:56:25 +04:00
parent fd8e7e1b28
commit 6231128288
2 changed files with 24 additions and 4 deletions

View File

@@ -6,6 +6,14 @@
<app-skeleton shape="text" height="16px" />
<app-skeleton shape="text" width="70%" height="16px" />
</section>
} @else if (error()) {
<section class="static-page__state">
<app-empty-state [title]="'common.errorTitle' | translate" [description]="'common.errorDescription' | translate">
<div slot="actions">
<app-button variant="primary" [routerLink]="homeRoute()">{{ 'staticPages.backHome' | translate }}</app-button>
</div>
</app-empty-state>
</section>
} @else if (notFound()) {
<section class="static-page__state">
<app-empty-state title="404" [description]="'staticPages.notFound' | translate">

View File

@@ -29,6 +29,7 @@ export class StaticPageComponent {
readonly loading = signal(true);
readonly notFound = signal(false);
readonly error = signal(false);
readonly title = signal('');
readonly homeRoute = signal('');
readonly dir = signal<'ltr' | 'rtl'>('ltr');
@@ -76,21 +77,32 @@ export class StaticPageComponent {
private loadByKey(key: string): void {
this.loading.set(true);
this.notFound.set(false);
this.error.set(false);
this.staticPageResolver.resolveByKey(key, this.languageService.currentLanguage()).subscribe(page => {
this.applyPage(page?.title ?? '', page?.html ?? '', !page);
this.staticPageResolver.resolveByKey(key, this.languageService.currentLanguage()).subscribe({
next: page => this.applyPage(page?.title ?? '', page?.html ?? '', !page),
error: () => this.applyError()
});
}
private loadByPath(path: string): void {
this.loading.set(true);
this.notFound.set(false);
this.error.set(false);
this.staticPageResolver.resolveByRoute(path, this.languageService.currentLanguage()).subscribe(page => {
this.applyPage(page?.title ?? '', page?.html ?? '', !page);
this.staticPageResolver.resolveByRoute(path, this.languageService.currentLanguage()).subscribe({
next: page => this.applyPage(page?.title ?? '', page?.html ?? '', !page),
error: () => this.applyError()
});
}
private applyError(): void {
this.title.set('');
this.safeHtml.set(this.sanitizer.bypassSecurityTrustHtml(''));
this.error.set(true);
this.loading.set(false);
}
private applyPage(title: string, html: string, notFound: boolean): void {
if (notFound) {
this.title.set('');