@@ -10,9 +10,11 @@ import { type Path } from '../jsutils/Path';
10
10
import devAssert from '../jsutils/devAssert' ;
11
11
import keyValMap from '../jsutils/keyValMap' ;
12
12
import instanceOf from '../jsutils/instanceOf' ;
13
+ import didYouMean from '../jsutils/didYouMean' ;
13
14
import isObjectLike from '../jsutils/isObjectLike' ;
14
15
import identityFunc from '../jsutils/identityFunc' ;
15
16
import defineToJSON from '../jsutils/defineToJSON' ;
17
+ import suggestionList from '../jsutils/suggestionList' ;
16
18
import defineToStringTag from '../jsutils/defineToStringTag' ;
17
19
import { type PromiseOrValue } from '../jsutils/PromiseOrValue' ;
18
20
import {
@@ -22,6 +24,7 @@ import {
22
24
} from '../jsutils/ObjMap' ;
23
25
24
26
import { Kind } from '../language/kinds' ;
27
+ import { print } from '../language/printer' ;
25
28
import {
26
29
type ScalarTypeDefinitionNode ,
27
30
type ObjectTypeDefinitionNode ,
@@ -44,6 +47,8 @@ import {
44
47
type ValueNode ,
45
48
} from '../language/ast' ;
46
49
50
+ import { GraphQLError } from '../error/GraphQLError' ;
51
+
47
52
import { valueFromASTUntyped } from '../utilities/valueFromASTUntyped' ;
48
53
49
54
import { type GraphQLSchema } from './schema' ;
@@ -1234,28 +1239,54 @@ export class GraphQLEnumType /* <T> */ {
1234
1239
1235
1240
serialize ( outputValue : mixed /* T */ ) : ?string {
1236
1241
const enumValue = this . _valueLookup . get ( outputValue ) ;
1237
- if ( enumValue ) {
1238
- return enumValue . name ;
1242
+ if ( enumValue === undefined ) {
1243
+ throw new GraphQLError (
1244
+ `Enum "${ this . name } " cannot represent value: ${ inspect ( outputValue ) } ` ,
1245
+ ) ;
1239
1246
}
1247
+ return enumValue . name ;
1240
1248
}
1241
1249
1242
1250
parseValue ( inputValue : mixed ) : ?any /* T */ {
1243
- if ( typeof inputValue === 'string' ) {
1244
- const enumValue = this . getValue ( inputValue ) ;
1245
- if ( enumValue ) {
1246
- return enumValue . value ;
1247
- }
1251
+ if ( typeof inputValue !== 'string' ) {
1252
+ const valueStr = inspect ( inputValue ) ;
1253
+ throw new GraphQLError (
1254
+ `Enum "${ this . name } " cannot represent non-string value: ${ valueStr } .` +
1255
+ didYouMeanEnumValue ( this , valueStr ) ,
1256
+ ) ;
1248
1257
}
1258
+
1259
+ const enumValue = this . getValue ( inputValue ) ;
1260
+ if ( enumValue == null ) {
1261
+ throw new GraphQLError (
1262
+ `Value "${ inputValue } " does not exist in "${ this . name } " enum.` +
1263
+ didYouMeanEnumValue ( this , inputValue ) ,
1264
+ ) ;
1265
+ }
1266
+ return enumValue . value ;
1249
1267
}
1250
1268
1251
1269
parseLiteral ( valueNode : ValueNode , _variables : ?ObjMap < mixed > ) : ?any /* T */ {
1252
1270
// Note: variables will be resolved to a value before calling this function.
1253
- if ( valueNode . kind === Kind . ENUM ) {
1254
- const enumValue = this . getValue ( valueNode . value ) ;
1255
- if ( enumValue ) {
1256
- return enumValue . value ;
1257
- }
1271
+ if ( valueNode . kind !== Kind . ENUM ) {
1272
+ const valueStr = print ( valueNode ) ;
1273
+ throw new GraphQLError (
1274
+ `Enum "${ this . name } " cannot represent non-enum value: ${ valueStr } .` +
1275
+ didYouMeanEnumValue ( this , valueStr ) ,
1276
+ valueNode ,
1277
+ ) ;
1258
1278
}
1279
+
1280
+ const enumValue = this . getValue ( valueNode . value ) ;
1281
+ if ( enumValue == null ) {
1282
+ const valueStr = print ( valueNode ) ;
1283
+ throw new GraphQLError (
1284
+ `Value "${ valueStr } " does not exist in "${ this . name } " enum.` +
1285
+ didYouMeanEnumValue ( this , valueStr ) ,
1286
+ valueNode ,
1287
+ ) ;
1288
+ }
1289
+ return enumValue . value ;
1259
1290
}
1260
1291
1261
1292
toConfig ( ) : { |
@@ -1294,6 +1325,16 @@ export class GraphQLEnumType /* <T> */ {
1294
1325
defineToStringTag ( GraphQLEnumType ) ;
1295
1326
defineToJSON ( GraphQLEnumType ) ;
1296
1327
1328
+ function didYouMeanEnumValue (
1329
+ enumType : GraphQLEnumType ,
1330
+ unknownValueStr : string ,
1331
+ ) : string {
1332
+ const allNames = enumType . getValues ( ) . map ( value => value . name ) ;
1333
+ const suggestedValues = suggestionList ( unknownValueStr , allNames ) ;
1334
+
1335
+ return didYouMean ( 'the enum value' , suggestedValues ) ;
1336
+ }
1337
+
1297
1338
function defineEnumValues (
1298
1339
typeName : string ,
1299
1340
valueMap : GraphQLEnumValueConfigMap /* <T> */ ,
0 commit comments