@@ -26,12 +26,23 @@ type SchemaFieldInfo =
2626/// A type alias to represent a Type name.
2727type TypeName = string
2828
29+ /// Contains data about a GQL operation error.
30+ type OperationErrorLocation =
31+ { /// The source line of the GraphQL operation document where the error occurred.
32+ Line : int
33+ /// The source column of the GraphQL operation document where the error occurred.
34+ Column : int }
35+
2936/// Contains data about a GQL operation error.
3037type OperationError =
3138 { /// The description of the error that happened in the operation.
3239 Message : string
40+ /// The source locations in the GraphQL operation document where the error occurred.
41+ Locations : OperationErrorLocation []
3342 /// The path to the field that produced the error while resolving its value.
34- Path : obj [] }
43+ Path : obj []
44+ /// Extension data attached to the error.
45+ Extensions : Map < string , obj > }
3546
3647/// Contains helpers to build HTTP header sequences to be used in GraphQLProvider Run methods.
3748module HttpHeaders =
@@ -394,17 +405,44 @@ module internal JsonValueHelper =
394405 |> Array.map ( firstUpper >> mapFieldValue)
395406
396407 let getErrors ( errors : JsonValue []) =
408+ let tryFindField fieldName ( fields : ( string * JsonValue ) []) =
409+ fields |> Array.tryFind ( fun ( name , _ ) -> name = fieldName) |> Option.map snd
410+
411+ let parsePath = function
412+ | Some ( JsonValue.Array path) ->
413+ let pathMapper = function
414+ | JsonValue.String x -> box x
415+ | JsonValue.Integer x -> box x
416+ | _ -> failwith " Error parsing response errors. An item in the path is neither a String nor a Number."
417+ path |> Array.map pathMapper
418+ | Some JsonValue.Null | None -> [||]
419+ | _ -> failwith " Error parsing response errors. Path field must be an Array."
420+
421+ let parseLocations = function
422+ | Some ( JsonValue.Array locations) ->
423+ let parseLocation = function
424+ | JsonValue.Record locationFields ->
425+ match tryFindField " line" locationFields, tryFindField " column" locationFields with
426+ | Some ( JsonValue.Integer line), Some ( JsonValue.Integer column) -> { Line = line; Column = column }
427+ | _ -> failwith " Error parsing response errors. A location item must contain Integer fields named \" line\" and \" column\" ."
428+ | _ -> failwith " Error parsing response errors. A location item is not a Record."
429+ locations |> Array.map parseLocation
430+ | Some JsonValue.Null | None -> [||]
431+ | _ -> failwith " Error parsing response errors. Locations field must be an Array."
432+
433+ let parseExtensions = function
434+ | Some ( JsonValue.Record fields) -> Serialization.deserializeMap fields
435+ | Some JsonValue.Null | None -> Map.empty
436+ | _ -> failwith " Error parsing response errors. Extensions field must be a Record."
437+
397438 let errorMapper = function
398439 | JsonValue.Record fields ->
399- match fields |> Array.tryFind ( fun ( name , _ ) -> name = " message" ), fields |> Array.tryFind ( fun ( name , _ ) -> name = " path" ) with
400- | Some (_, JsonValue.String message), Some (_, JsonValue.Array path) ->
401- let pathMapper = function
402- | JsonValue.String x -> box x
403- | JsonValue.Integer x -> box x
404- | _ -> failwith " Error parsing response errors. A item in the path is neither a String or a Number."
405- { Message = message; Path = Array.map pathMapper path }
406- | Some (_, JsonValue.String message), None->
407- { Message = message; Path = [||]}
440+ match tryFindField " message" fields with
441+ | Some ( JsonValue.String message) ->
442+ { Message = message
443+ Locations = tryFindField " locations" fields |> parseLocations
444+ Path = tryFindField " path" fields |> parsePath
445+ Extensions = tryFindField " extensions" fields |> parseExtensions }
408446 | _ -> failwith " Error parsing response errors. Unsupported errors field format."
409447 | other -> failwithf " Error parsing response errors. Expected error to be a Record type, but it is %s ." ( other.ToString())
410448 Array.map errorMapper errors
0 commit comments