@@ -6,6 +6,7 @@ import { UmbControllerBase } from '@umbraco-cms/backoffice/class-api';
6
6
import { UmbContextConsumerController } from '@umbraco-cms/backoffice/context-api' ;
7
7
import { UMB_NOTIFICATION_CONTEXT , type UmbNotificationOptions } from '@umbraco-cms/backoffice/notification' ;
8
8
import type { UmbDataSourceResponse } from '@umbraco-cms/backoffice/repository' ;
9
+ import type { ProblemDetails } from '@umbraco-cms/backoffice/external/backend-api' ;
9
10
10
11
export class UmbResourceController extends UmbControllerBase {
11
12
#promise: Promise < any > ;
@@ -57,8 +58,8 @@ export class UmbResourceController extends UmbControllerBase {
57
58
* If the executor function throws an error, then show the details in a notification.
58
59
*/
59
60
async tryExecuteAndNotify < T > ( options ?: UmbNotificationOptions ) : Promise < UmbDataSourceResponse < T > > {
60
- const { data, error : _error } = await UmbResourceController . tryExecute < T > ( this . #promise) ;
61
- const error : any = _error ;
61
+ const { data, error } = await UmbResourceController . tryExecute < T > ( this . #promise) ;
62
+
62
63
if ( error ) {
63
64
/**
64
65
* Determine if we want to show a notification or just log the error to the console.
@@ -71,18 +72,33 @@ export class UmbResourceController extends UmbControllerBase {
71
72
} else {
72
73
console . group ( 'ApiError caught in UmbResourceController' ) ;
73
74
console . error ( 'Request failed' , error . request ) ;
74
- console . error ( 'ProblemDetails ' , error . body ) ;
75
+ console . error ( 'Request body ' , error . body ) ;
75
76
console . error ( 'Error' , error ) ;
76
77
78
+ let problemDetails : ProblemDetails | null = null ;
79
+
77
80
// ApiError - body could hold a ProblemDetails from the server
78
81
if ( typeof error . body !== 'undefined' && ! ! error . body ) {
79
82
try {
80
- ( error as any ) . body = typeof error . body === 'string' ? JSON . parse ( error . body ) : error . body ;
83
+ ( error as any ) . body = problemDetails = typeof error . body === 'string' ? JSON . parse ( error . body ) : error . body ;
81
84
} catch ( e ) {
82
85
console . error ( 'Error parsing error body (expected JSON)' , e ) ;
83
86
}
84
87
}
85
88
89
+ /**
90
+ * Check if the operation status ends with `ByNotification` and if so, don't show a notification
91
+ * This is a special case where the operation was cancelled by the server and the client gets a notification header instead.
92
+ */
93
+ let isCancelledByNotification = false ;
94
+ if (
95
+ problemDetails ?. operationStatus &&
96
+ typeof problemDetails . operationStatus === 'string' &&
97
+ problemDetails . operationStatus . endsWith ( 'ByNotification' )
98
+ ) {
99
+ isCancelledByNotification = true ;
100
+ }
101
+
86
102
// Go through the error status codes and act accordingly
87
103
switch ( error . status ?? 0 ) {
88
104
case 401 : {
@@ -103,14 +119,14 @@ export class UmbResourceController extends UmbControllerBase {
103
119
case 500 :
104
120
// Server Error
105
121
106
- if ( this . #notificationContext) {
107
- let headline = error . body ?. title ?? error . name ?? 'Server Error' ;
122
+ if ( ! isCancelledByNotification && this . #notificationContext) {
123
+ let headline = problemDetails ?. title ?? error . name ?? 'Server Error' ;
108
124
let message = 'A fatal server error occurred. If this continues, please reach out to your administrator.' ;
109
125
110
126
// Special handling for ObjectCacheAppCache corruption errors, which we are investigating
111
127
if (
112
- error . body ?. detail ?. includes ( 'ObjectCacheAppCache' ) ||
113
- error . body ?. detail ?. includes ( 'Umbraco.Cms.Infrastructure.Scoping.Scope.DisposeLastScope()' )
128
+ problemDetails ?. detail ?. includes ( 'ObjectCacheAppCache' ) ||
129
+ problemDetails ?. detail ?. includes ( 'Umbraco.Cms.Infrastructure.Scoping.Scope.DisposeLastScope()' )
114
130
) {
115
131
headline = 'Please restart the server' ;
116
132
message =
@@ -128,12 +144,14 @@ export class UmbResourceController extends UmbControllerBase {
128
144
break ;
129
145
default :
130
146
// Other errors
131
- if ( this . #notificationContext) {
147
+ if ( ! isCancelledByNotification && this . #notificationContext) {
132
148
this . #notificationContext. peek ( 'danger' , {
133
149
data : {
134
- headline : error . body ?. title ?? error . name ?? 'Server Error' ,
135
- message : error . body ?. detail ?? error . message ?? 'Something went wrong' ,
136
- structuredList : error . body . errors ,
150
+ headline : problemDetails ?. title ?? error . name ?? 'Server Error' ,
151
+ message : problemDetails ?. detail ?? error . message ?? 'Something went wrong' ,
152
+ structuredList : problemDetails ?. errors
153
+ ? ( problemDetails . errors as Record < string , Array < unknown > > )
154
+ : undefined ,
137
155
} ,
138
156
...options ,
139
157
} ) ;
0 commit comments