Improve frontend error handling

This commit is contained in:
shamoon
2023-05-17 12:46:04 -07:00
parent c12c7c23fb
commit 4e295f0c71
7 changed files with 274 additions and 275 deletions

View File

@@ -38,6 +38,9 @@ export abstract class EditDialogComponent<
@Output()
succeeded = new EventEmitter()
@Output()
failed = new EventEmitter()
networkActive = false
closeEnabled = false
@@ -141,7 +144,7 @@ export abstract class EditDialogComponent<
error: (error) => {
this.error = error.error
this.networkActive = false
this.succeeded.next(error)
this.failed.next(error)
},
})
}

View File

@@ -4,5 +4,10 @@
[class]="toast.classname"
(hidden)="toastService.closeToast(toast)">
<p>{{toast.content}}</p>
<details *ngIf="toast.error">
<pre class="p-2 m-0 bg-light text-dark">
{{toast.error}}
</pre>
</details>
<p class="mb-0" *ngIf="toast.action"><button class="btn btn-sm btn-outline-secondary" (click)="toastService.closeToast(toast); toast.action()">{{toast.actionName}}</button></p>
</ngb-toast>

View File

@@ -20,3 +20,8 @@
border-bottom-left-radius: inherit;
border-bottom-right-radius: inherit;
}
pre {
white-space: pre-line;
--bs-bg-opacity: .25;
}

View File

@@ -136,26 +136,18 @@ export abstract class ManagementListComponent<T extends ObjectWithId>
backdrop: 'static',
})
activeModal.componentInstance.dialogMode = 'create'
activeModal.componentInstance.succeeded.subscribe({
next: () => {
if (activeModal.componentInstance.error) {
this.toastService.showInfo(
$localize`Error occurred while creating ${this.typeName} : ${activeModal.componentInstance.error}.`
)
} else {
this.reloadData()
this.toastService.showInfo(
$localize`Successfully created ${this.typeName}.`
)
}
},
error: (e) => {
this.toastService.showInfo(
$localize`Error occurred while creating ${this.typeName} : ${
e.error ?? e.message ?? e.toString()
}.`
)
},
activeModal.componentInstance.succeeded.subscribe(() => {
this.reloadData()
this.toastService.showInfo(
$localize`Successfully created ${this.typeName}.`
)
})
activeModal.componentInstance.failed.subscribe((e) => {
this.toastService.showError(
$localize`Error occurred while creating ${this.typeName}.`,
10000,
JSON.stringify(e)
)
})
}
@@ -165,31 +157,18 @@ export abstract class ManagementListComponent<T extends ObjectWithId>
})
activeModal.componentInstance.object = object
activeModal.componentInstance.dialogMode = 'edit'
activeModal.componentInstance.succeeded.subscribe({
next: () => {
if (activeModal.componentInstance.error) {
const errorDetail = activeModal.componentInstance.error.error
? activeModal.componentInstance.error.error[0]
: null
this.toastService.showInfo(
$localize`Error occurred while saving ${this.typeName}${
errorDetail ? ': ' + errorDetail : ''
}.`
)
} else {
this.reloadData()
this.toastService.showInfo(
$localize`Successfully updated ${this.typeName}.`
)
}
},
error: (e) => {
this.toastService.showInfo(
$localize`Error occurred while saving ${
this.typeName
} : ${e.toString()}.`
)
},
activeModal.componentInstance.succeeded.subscribe(() => {
this.reloadData()
this.toastService.showInfo(
$localize`Successfully updated ${this.typeName}.`
)
})
activeModal.componentInstance.failed.subscribe((e) => {
this.toastService.showError(
$localize`Error occurred while saving ${this.typeName}.`,
10000,
JSON.stringify(e)
)
})
}

View File

@@ -590,9 +590,10 @@ export class SettingsComponent
},
error: (error) => {
this.toastService.showError(
$localize`An error occurred while saving settings.`
$localize`An error occurred while saving settings.`,
10000,
JSON.stringify(error)
)
console.log(error)
},
})
}
@@ -625,9 +626,9 @@ export class SettingsComponent
},
(error) => {
this.toastService.showError(
$localize`Error while storing settings on server: ${JSON.stringify(
error.error
)}`
$localize`Error while storing settings on server.`,
10000,
JSON.stringify(error)
)
}
)
@@ -649,33 +650,35 @@ export class SettingsComponent
modal.componentInstance.object = user
modal.componentInstance.succeeded
.pipe(takeUntil(this.unsubscribeNotifier))
.subscribe({
next: (newUser: PaperlessUser) => {
if (
newUser.id === this.settings.currentUser.id &&
(modal.componentInstance as UserEditDialogComponent).passwordIsSet
) {
this.toastService.showInfo(
$localize`Password has been changed, you will be logged out momentarily.`
)
setTimeout(() => {
window.location.href = `${window.location.origin}/accounts/logout/?next=/accounts/login/`
}, 2500)
} else {
this.toastService.showInfo(
$localize`Saved user "${newUser.username}".`
)
this.usersService.listAll().subscribe((r) => {
this.users = r.results
this.initialize()
})
}
},
error: (e) => {
this.toastService.showError(
$localize`Error saving user: ${e.toString()}.`
.subscribe((newUser: PaperlessUser) => {
if (
newUser.id === this.settings.currentUser.id &&
(modal.componentInstance as UserEditDialogComponent).passwordIsSet
) {
this.toastService.showInfo(
$localize`Password has been changed, you will be logged out momentarily.`
)
},
setTimeout(() => {
window.location.href = `${window.location.origin}/accounts/logout/?next=/accounts/login/`
}, 2500)
} else {
this.toastService.showInfo(
$localize`Saved user "${newUser.username}".`
)
this.usersService.listAll().subscribe((r) => {
this.users = r.results
this.initialize()
})
}
})
modal.componentInstance.failed
.pipe(takeUntil(this.unsubscribeNotifier))
.subscribe((e) => {
this.toastService.showError(
$localize`Error saving user.`,
10000,
JSON.stringify(e)
)
})
}
@@ -701,7 +704,9 @@ export class SettingsComponent
},
error: (e) => {
this.toastService.showError(
$localize`Error deleting user: ${e.toString()}.`
$localize`Error deleting user.`,
10000,
JSON.stringify(e)
)
},
})
@@ -717,19 +722,21 @@ export class SettingsComponent
modal.componentInstance.object = group
modal.componentInstance.succeeded
.pipe(takeUntil(this.unsubscribeNotifier))
.subscribe({
next: (newGroup) => {
this.toastService.showInfo($localize`Saved group "${newGroup.name}".`)
this.groupsService.listAll().subscribe((r) => {
this.groups = r.results
this.initialize()
})
},
error: (e) => {
this.toastService.showError(
$localize`Error saving group: ${e.toString()}.`
)
},
.subscribe((newGroup) => {
this.toastService.showInfo($localize`Saved group "${newGroup.name}".`)
this.groupsService.listAll().subscribe((r) => {
this.groups = r.results
this.initialize()
})
})
modal.componentInstance.failed
.pipe(takeUntil(this.unsubscribeNotifier))
.subscribe((e) => {
this.toastService.showError(
$localize`Error saving group.`,
10000,
JSON.stringify(e)
)
})
}
@@ -755,7 +762,9 @@ export class SettingsComponent
},
error: (e) => {
this.toastService.showError(
$localize`Error deleting group: ${e.toString()}.`
$localize`Error deleting group.`,
10000,
JSON.stringify(e)
)
},
})
@@ -775,22 +784,24 @@ export class SettingsComponent
modal.componentInstance.object = account
modal.componentInstance.succeeded
.pipe(takeUntil(this.unsubscribeNotifier))
.subscribe({
next: (newMailAccount) => {
this.toastService.showInfo(
$localize`Saved account "${newMailAccount.name}".`
)
this.mailAccountService.clearCache()
this.mailAccountService.listAll().subscribe((r) => {
this.mailAccounts = r.results
this.initialize()
})
},
error: (e) => {
this.toastService.showError(
$localize`Error saving account: ${e.toString()}.`
)
},
.subscribe((newMailAccount) => {
this.toastService.showInfo(
$localize`Saved account "${newMailAccount.name}".`
)
this.mailAccountService.clearCache()
this.mailAccountService.listAll().subscribe((r) => {
this.mailAccounts = r.results
this.initialize()
})
})
modal.componentInstance.failed
.pipe(takeUntil(this.unsubscribeNotifier))
.subscribe((e) => {
this.toastService.showError(
$localize`Error saving account.`,
10000,
JSON.stringify(e)
)
})
}
@@ -817,7 +828,9 @@ export class SettingsComponent
},
error: (e) => {
this.toastService.showError(
$localize`Error deleting mail account: ${e.toString()}.`
$localize`Error deleting mail account.`,
10000,
JSON.stringify(e)
)
},
})
@@ -833,23 +846,23 @@ export class SettingsComponent
modal.componentInstance.object = rule
modal.componentInstance.succeeded
.pipe(takeUntil(this.unsubscribeNotifier))
.subscribe({
next: (newMailRule) => {
this.toastService.showInfo(
$localize`Saved rule "${newMailRule.name}".`
)
this.mailRuleService.clearCache()
this.mailRuleService.listAll().subscribe((r) => {
this.mailRules = r.results
.subscribe((newMailRule) => {
this.toastService.showInfo($localize`Saved rule "${newMailRule.name}".`)
this.mailRuleService.clearCache()
this.mailRuleService.listAll().subscribe((r) => {
this.mailRules = r.results
this.initialize(true)
})
},
error: (e) => {
this.toastService.showError(
$localize`Error saving rule: ${e.toString()}.`
)
},
this.initialize(true)
})
})
modal.componentInstance.failed
.pipe(takeUntil(this.unsubscribeNotifier))
.subscribe((e) => {
this.toastService.showError(
$localize`Error saving rule.`,
10000,
JSON.stringify(e)
)
})
}
@@ -876,7 +889,9 @@ export class SettingsComponent
},
error: (e) => {
this.toastService.showError(
$localize`Error deleting mail rule: ${e.toString()}.`
$localize`Error deleting mail rule.`,
10000,
JSON.stringify(e)
)
},
})

View File

@@ -13,6 +13,8 @@ export interface Toast {
actionName?: string
classname?: string
error?: any
}
@Injectable({
@@ -30,12 +32,13 @@ export class ToastService {
this.toastsSubject.next(this.toasts)
}
showError(content: string, delay: number = 10000) {
showError(content: string, delay: number = 10000, error: any = null) {
this.show({
title: $localize`Error`,
content: content,
delay: delay,
classname: 'error',
error,
})
}