Validare JSON

Incolla il documento che qualcosa ti sta rifiutando e scopri dove si inceppa. Un «non valido» non basta: qui escono la riga, la colonna e il frammento di testo con il punto marcato, perché il messaggio di un parser indica quasi sempre il posto in cui si è accorto del problema e non il posto in cui il problema è. Niente viene caricato.

Risultato

La risposta compare qui mentre scrivi.

  • Dove gira

    Non viene caricato nulla, perché non c’è nessun file: il calcolo avviene in questa pagina.

  • Nessuna coda, nessun account

    Risponde alla velocità della tua macchina e non chiede mai chi sei.

  • Tutte le volte che vuoi

    Non si conta né si limita nulla: rispondere di nuovo non ci costa niente.

Come funziona

  1. Incolla il documento che ti stanno rifiutando.
  2. Leggi riga e colonna, e il frammento con il punto segnalato.
  3. Correggi e reincolla. Non è stato caricato niente.

La riga che dice il parser e la riga dell’errore

Un parser JSON legge in avanti e si ferma nel primo punto in cui la sequenza non può più essere completata. Quel punto è dove se ne accorge, non dove hai sbagliato: se manchi una virgola alla fine della riga 12, l’errore lo troverai segnalato all’inizio della riga 13, dove compare una virgoletta che a quel punto non ci può stare.

Sapere questo dimezza il tempo di ricerca. La regola pratica è guardare la riga indicata e quella prima, in quest’ordine, e chiedersi cosa manchi alla fine della precedente. Il frammento evidenziato qui serve proprio a questo: mostra il contesto invece della sola coordinata, perché la coordinata da sola manda a cercare nel posto sbagliato.

Ogni browser scrive il messaggio a modo suo

Lo stesso documento rotto produce tre frasi diverse in tre motori diversi. V8, in Chrome e in Node, dice `Unexpected token } in JSON at position 42`; Firefox parla di `SyntaxError: JSON.parse: expected property name`; Safari usa un’altra formulazione ancora. Nessuna delle tre è più corretta delle altre: la specifica non prescrive i messaggi.

Da qui la conseguenza pratica: cercare su Google la frase esatta di un errore JSON funziona male, perché la stessa causa ha tre testi. Quello che si trasferisce fra ambienti è la posizione, e per questo qui viene convertita in riga e colonna — che è come è organizzato il file che stai guardando, mentre l’offset in caratteri non lo è.

I quattro errori che spiegano quasi tutto

Una virgola dopo l’ultimo elemento di un array o di un oggetto; una virgola che manca fra due elementi; le virgolette singole al posto di quelle doppie, o le chiavi senza virgolette; un commento. Sono quattro forme che coprono la grande maggioranza dei documenti rifiutati, e tutte e quattro sono cose che JavaScript accetterebbe volentieri.

È proprio da lì che vengono: da qualcuno che ha scritto JSON pensando a un oggetto JavaScript. Il quinto caso, meno frequente ma più insidioso, è una barra rovesciata dentro una stringa — un percorso di Windows come `C:\Users` va scritto con la barra doppia, altrimenti `\U` viene letto come l’inizio di una sequenza di escape e il messaggio d’errore parla di caratteri Unicode.

Valido non vuol dire corretto

Questa pagina risponde a una domanda sola: la sintassi regge. Non sa quali campi la tua API si aspetti, non sa se `stato` debba essere un numero o una stringa, e non ha nessuna opinione su un array vuoto dove doveva esserci qualcosa.

Per quel livello serve uno schema — JSON Schema, o la validazione che l’API applica per conto suo — e la distinzione è utile proprio quando le due risposte divergono. «Valido qui e rifiutato là» quasi sempre vuol dire che il documento è sintatticamente giusto e semanticamente incompleto, e a quel punto la risposta di errore dell’API è la fonte da leggere, non il documento.

Le tabulazioni e la colonna che non torna

La colonna qui viene contata in caratteri, non in colonne visive: una tabulazione conta uno. Il tuo editor probabilmente la disegna larga quattro o otto, quindi il numero indicato e la posizione del cursore non coincidono in un file rientrato con tabulazioni.

Non è un difetto da correggere ma un’ambiguità da conoscere, perché la larghezza di una tabulazione è una scelta di visualizzazione e non un fatto del file. Se i due numeri litigano, la riga resta affidabile e il contesto evidenziato è il modo per trovare il punto esatto senza contare caratteri.

Cosa si può leggere da un documento valido

Quando il documento passa, non esce solo un via libera. Escono il tipo del livello più esterno — oggetto o array —, il numero di chiavi, la profondità di annidamento e la dimensione in byte, che sono le quattro cose che si vogliono sapere di un documento che non si è scritto.

La profondità in particolare è utile prima di dare il documento a qualcos’altro: molti servizi impongono un limite di annidamento e lo dichiarano di rado, e una struttura profonda venti livelli è quasi sempre il segno di un export automatico piuttosto che di un modello dati pensato. Il numero di chiavi al livello esterno dice invece se stai guardando un elenco o un singolo record.

I numeri grandi vengono segnalati a parte

Un documento può essere perfettamente valido e contenere comunque un numero che nessun parser JavaScript conserva esatto: oltre 9.007.199.254.740.991 la doppia precisione arrotonda, e l’identificatore che leggi non è più quello che era stato scritto.

La segnalazione è separata dal verdetto perché sono due cose diverse: la sintassi è a posto, il valore no. Metterle insieme farebbe passare per «non valido» un documento che ogni sistema accetterà, e trascurare la seconda lascerebbe partire un identificatore modificato senza che nessuno lo veda. La correzione, dove è possibile, sta a monte: quei valori vanno mandati come stringhe.

Perché non c’è un’anteprima formattata

Un documento rotto non si può formattare: per riscriverlo con il rientro bisogna prima averlo analizzato, e l’analisi è esattamente ciò che è fallito. Le anteprime che si vedono in giro le fabbricano con un’espressione regolare, e su un documento rotto producono un rientro sbagliato proprio intorno al punto dell’errore, che è il posto in cui inganna di più.

Quando il documento è valido, il rientro è comunque un’altra domanda e ha la sua pagina. Tenerle separate significa che questa può dire una cosa sola e dirla bene, che è il criterio con cui su questo sito si decide se due strumenti sono due pagine.

Perché un documento rifiutato non dovrebbe passare da un server

Il documento che si incolla in un validatore è, per definizione, quello che sta causando un problema in produzione: la risposta che ha fatto fallire un’integrazione, il payload di un ordine, il corpo di una richiesta con dentro i dati di una persona. È materiale reale, non un esempio.

Per questo il controllo avviene qui e non altrove: il parser è quello del browser, il conto dura pochi millisecondi e nessuna richiesta porta con sé il testo. Nel senso del GDPR non c’è nessun trasferimento da giustificare, e nel senso pratico non c’è nessun log altrui in cui il tuo documento possa restare.

Validare JSON: domande frequenti

Mi dice riga 13 e l’errore sembra alla 12: perché?

Perché un parser si ferma dove la sequenza diventa impossibile, non dove manca qualcosa. Una virgola dimenticata alla fine della riga 12 diventa un carattere inatteso all’inizio della 13. Guarda sempre anche la riga precedente a quella indicata: nella grande maggioranza dei casi il pezzo mancante è lì.

Il documento è valido e la mia API lo rifiuta lo stesso: cosa manca?

Quasi certamente la parte semantica. Qui si controlla la sintassi; la tua API controlla anche quali campi ci siano, di che tipo siano e quali valori ammettano. In quel caso la fonte utile è il corpo della risposta di errore, che di solito nomina il campo, e non il documento che hai incollato.

Si inceppa alla colonna 1 e non vedo niente di strano: cosa guardo?

Di solito il documento non inizia con JSON. Le cause frequenti sono un BOM invisibile all’inizio del file, una pagina di errore HTML salvata con estensione .json, oppure una risposta che comincia con degli spazi e con del testo di log. Anche una riga vuota davanti non è un problema, mentre qualsiasi altro carattere lo è.

Perché mi avvisa su un numero se il documento è valido?

Perché sono due domande separate. La sintassi è corretta, ma il documento contiene un intero oltre 9.007.199.254.740.991, e a quel punto ogni parser JSON basato su JavaScript lo arrotonda. Il documento verrà accettato ovunque e l’identificatore che ne esce sarà un altro numero: è utile saperlo prima e non dopo.

Il documento esce dalla mia macchina?

No. Il controllo usa il parser del browser e avviene nella scheda, quindi non parte nessuna richiesta con il testo. Qui pesa più che altrove, perché il documento che si porta a un validatore è per definizione quello vero che sta rompendo qualcosa in produzione.

Altri strumenti