Fejlhåndtering
I denne artikel:
Introduktion
Når der opstår fejl, svarer API'et med detaljeret information omkring hvad der gik galt, samt hvilken del af forespørgslen der forårsagede fejlen. Et fejl-response kan høre under en af følgende to kategorier: Interne fejl og valideringsfejl.
Uanset typen af fejl, vil svaret altid være struktureret på samme måde, og indeholde en message
som beskriver fejlen, samt en category
som beskriver fejltypen, og en locations
entry som beskriver hvilket sted i forespørgslen fejlen opstod. Ligeledes suppleres med path
, som viser stien til forespørgslen eller mutationen i den pågældende forespørgsel som skabte fejlen –dette kan være nyttigt hvis flere forespørgsler eller mutationer er samlet i én forespørgsel.
Læs også: API Rate Limits
Fejl under afvikling af mutationer
Hvis der opstår fejl under en mutation, annulleres alle ændringer som udføres af den pågældende request. Derfor vil, uanset grunden til fejlen, alle data forblive uændret, som hvis mutationen slet ikke var blevet eksekveret. Dette sikrer integriteten af dine data, og gør systemets aktuelle tilstand gennemskuelig på alle tidspunkter.
Interne fejl
Opstår en serverfejl, vil du blive præsenteret for en fejl i stil med denne:
{
"errors": [
{
"message": "Internal server error",
"category": "internal",
"locations": [
{
"line": 2,
"column": 3
}
],
"path": [
"orders"
]
}
],
"data": []
}
Valideringsfejl
Når en forespørgsel eller mutation, som tager input udføres, valideres det suplerede input for at sikre gyldigheden af de supplerede data, for ideelt set at gøre det umuligt, sætte din løsning i en ugyldig eller korrumperet tilstand. Hvis dit input anses for at være ugyldigt, vil content
feltet af resultatet være null
, og detaljer omkring valideringsfejlen være suppleret i errors
feltet.
Alle fejl i et hvert errors
felt af et payload implementerer ClientErrorInterface
interfacet:
interface ClientErrorInterface {
field: [String!]!
message: String!
name: String!
}
Typer der implementerer dette interface grupperes efter forretningsdomæne, så relaterede forespørgsler og mutationer bruger den samme konkrete fejltype. Dette demonstreres i følgende eksempel med PageTreeClientError
som den konkrete type.
Hvert af disse felter uddybes nærmere i de følgende eksempler.
Eksempel: Oprettelse af en side
I dette eksempel forsøger vi at oprette en ny side.
Vores GraphQL forespørgsel ser således ud:
QUERY
mutation pageCreate($input: PageCreateInput!) {
pageCreate(input: $input) {
content {
id
}
errors {
field
message
name
code
id
}
}
}
VARIABLES
{
"input": {
"folderId": 1,
"parentId": 1,
"languageLayerAccess": [
1,
2
],
"menuDisplaySettings": [
1
],
"translations": [
{
"languageId": 1,
"data": {
"link": "pageLink1"
}
},
{
"languageId": 2,
"data": {
"title": "pageTitle2"
}
}
],
"type": "TEXT",
"userAccessSettings": [
1
]
}
}
Response
{
"data": {
"content": null,
"errors": [
{
"field": [
"input",
"folderId"
],
"message": "Unexpected 'folderId'. Expected exactly one of: ['folderId', 'parentId'].",
"name": "EXCLUSIVE_OR_UNEXPECTED_ERROR",
"code": "EXCLUSIVE_OR_UNEXPECTED_ERROR",
"id": "EXCLUSIVE_OR_UNEXPECTED_ERROR"
},
{
"field": [
"input",
"parentId"
],
"message": "Unexpected 'parentId'. Expected exactly one of: ['folderId', 'parentId'].",
"name": "EXCLUSIVE_OR_UNEXPECTED_ERROR",
"code": "EXCLUSIVE_OR_UNEXPECTED_ERROR",
"id": "EXCLUSIVE_OR_UNEXPECTED_ERROR"
},
{
"field": [
"input",
"parentId"
],
"message": "Page with id '123' does not exist.",
"name": "ENTITY_NOT_FOUND_ERROR",
"code": "ENTITY_NOT_FOUND_ERROR",
"id": "ENTITY_NOT_FOUND_ERROR"
},
{
"field": [
"input",
"translations"
],
"message": "Missing required 'title' in primary language: 1",
"name": "MISSING_PRIMARY_TITLE_ERROR",
"code": "MISSING_PRIMARY_TITLE_ERROR",
"id": "MISSING_PRIMARY_TITLE_ERROR"
}
]
}
}
Dette betyder således, at vores input overtræder 4 forskellige (men ikke unikke) begrænsninger:
input.folderId
: Der forventes nøjagtigt ét affolderId
ogparentId
felterne.input.parentId
: Der forventes nøjagtigt ét affolderId
ogparentId
felterne.input.parentId
: Det angivne ID123
referer ikke til en eksisterende side.input.translations
: Vi supplerede ikke entitle
oversættelse til det primære sprog, i dette tilfælde sproget med ID1
.
Følgende bør noteres i denne sammenhæng:
Mens 4 begrænsninger for inputtet blev overtrådt, så blev både (2) og (3) associeret med det samme felt i inputtet, og to af overtrædelserne skyldes den samme begrænsning, men på to forskellige felter. Endelig, mens fraværet af en "titel" til oversættelsen af det primære sprog kunne have haft sit felt opført som "input.translations.0", var dette ikke tilfældet; dette er sådan, selvom der ikke gives oversættelser til primær-sproget, for at sammenhængen med overtrædelsen stadigt er gennemskuelig.
Hvad dette ligeledes demonstrerer er, at typen PageTreeClientError
inkluderer yderligere to felter som ikke er til stede i ClientErrorInterface
: name
og id
.
Den fulde definition af PageTreeClientError
er:
interface ClientErrorInterface {
field: [String!]!
message: String!
name: String!
}
id
-feltet indeholder en unik maskinlæsbar identifikator for fejltypen. I øjeblikket vil dette have den samme værdi som feltet name
i mange tilfælde, dog vil dette være et UUID i fremtiden.
code
-feltet indeholder fejlkoden for fejl af denne type og er en optælling, der giver udviklere mulighed for at inspicere skemaet og vide nøjagtigt, hvilke fejl der kan forventes fra en given forespørgsel eller mutation.
Selvom det kan synes overflødigt at have både name
og code
felterne, er begrundelsen bag dette, at have en tekstversion af code
feltet tillader API-klienter at skrive generelle fragmenterede selects, såsom:
fragment ClientErrorFields on ClientErrorInterface {
field
message
name
}
Dette kan derefter benyttes til at forenkle ovenstående pageCreate
mutation:
mutation pageCreate($input: PageCreateInput!) {
pageCreate(input: $input) {
content {
id
}
errors {
...ClientErrorFields
code
id
}
}
}
fragment ClientErrorFields on ClientErrorInterface {
field
message
name
}
Valideringsfejl (udfaset)
En anden type fejl, der kan opstå, er en valideringsfejl. Dette sker, hvis nogle af de leverede data er ugyldige. Følgende eksempel demonstrerer dette ved at forsøge at oprette en side inde i en mappe, der ikke findes:
POST shop99999.mywebshop.io/api/graphql
(Erstat "shop99999" med dit eget shop nummer)
mutation {
pageCreate(input: {folderId: 123, type: text}) {
id
}
}
Response
{
"errors": [
{
"message": "The given data was invalid.",
"category": "graphql",
"locations": [
{
"line": 2,
"column": 3
}
],
"path": [
"pageCreate"
],
"validation": {
"input.folderId": [
"validation.exists"
]
}
}
],
"data": []
}
I tilfælde af valideringsfejl indeholder errors
delen af responset ligeledes et validation
afsnit, der enumererer alle valideringsfejl, indekseret af stien til de ugyldige data i inputtet.