@@ -6,7 +6,13 @@ import {
6
6
GqlContextType as ContextKey ,
7
7
GqlExecutionContext ,
8
8
} from '@nestjs/graphql' ;
9
- import { isNotFalsy , setHas , setOf , simpleSwitch } from '@seedcompany/common' ;
9
+ import {
10
+ entries ,
11
+ isNotFalsy ,
12
+ setHas ,
13
+ setOf ,
14
+ simpleSwitch ,
15
+ } from '@seedcompany/common' ;
10
16
import * as Edge from 'edgedb' ;
11
17
import * as EdgeDBTags from 'edgedb/dist/errors/tags.js' ;
12
18
import { GraphQLError , GraphQLResolveInfo } from 'graphql' ;
@@ -17,11 +23,14 @@ import {
17
23
Exception ,
18
24
getParentTypes ,
19
25
getPreviousList ,
26
+ InputException ,
20
27
JsonSet ,
28
+ NotFoundException ,
21
29
} from '~/common' ;
22
30
import type { ConfigService } from '~/core' ;
23
31
import * as Neo from '../database/errors' ;
24
32
import { ExclusivityViolationError } from '../edgedb/exclusivity-violation.error' ;
33
+ import { ResourcesHost } from '../resources/resources.host' ;
25
34
import { isSrcFrame } from './is-src-frame' ;
26
35
import { normalizeFramePath } from './normalize-frame-path' ;
27
36
@@ -35,7 +44,10 @@ export interface ExceptionJson {
35
44
36
45
@Injectable ( )
37
46
export class ExceptionNormalizer {
38
- constructor ( @Inject ( 'CONFIG' ) private readonly config ?: ConfigService ) { }
47
+ constructor (
48
+ @Inject ( 'CONFIG' ) private readonly config ?: ConfigService ,
49
+ private readonly resources ?: ResourcesHost ,
50
+ ) { }
39
51
40
52
normalize ( ex : Error , context ?: ArgumentsHost ) : ExceptionJson {
41
53
const {
@@ -119,6 +131,8 @@ export class ExceptionNormalizer {
119
131
? GqlExecutionContext . create ( context as any )
120
132
: undefined ;
121
133
134
+ ex = this . wrapIDNotFoundError ( ex , gqlContext ) ;
135
+
122
136
if ( ex instanceof ExclusivityViolationError ) {
123
137
ex = DuplicateException . fromDB ( ex , gqlContext ) ;
124
138
} else if ( ex instanceof Edge . EdgeDBError ) {
@@ -165,6 +179,43 @@ export class ExceptionNormalizer {
165
179
return { codes : [ 'Server' ] } ;
166
180
}
167
181
182
+ /**
183
+ * Convert ID not found database errors from user input
184
+ * to user input NotFound error with that input path.
185
+ */
186
+ private wrapIDNotFoundError (
187
+ ex : Error ,
188
+ gqlContext : GqlExecutionContext | undefined ,
189
+ ) {
190
+ if ( ! ( ex instanceof Edge . CardinalityViolationError ) ) {
191
+ return ex ;
192
+ }
193
+
194
+ const matched = ex . message . match ( / ' ( .+ ) ' w i t h i d ' ( .+ ) ' d o e s n o t e x i s t / ) ;
195
+ if ( ! matched ) {
196
+ return ex ;
197
+ }
198
+ const [ _ , type , id ] = matched ;
199
+
200
+ const inputPath = entries ( InputException . getFlattenInput ( gqlContext ) ) . find (
201
+ ( [ _ , value ] ) => value === id ,
202
+ ) ?. [ 0 ] ;
203
+ if ( ! inputPath ) {
204
+ return ex ;
205
+ }
206
+
207
+ const typeName = this . resources
208
+ ? this . resources . getByEdgeDB ( type ) . name
209
+ : type ;
210
+ const wrapped = new NotFoundException (
211
+ `${ typeName } could not be found` ,
212
+ inputPath ,
213
+ ex ,
214
+ ) ;
215
+ wrapped . stack = ex . stack ;
216
+ return wrapped ;
217
+ }
218
+
168
219
private httpException ( ex : Nest . HttpException ) {
169
220
const res = ex . getResponse ( ) ;
170
221
const {
0 commit comments