2012-11-10 9 views
9

Non si tratta di come gestire o correggere un JSON guasto, ma di come spiegare all'utente dove si trova l'errore nel JSON difettoso.Analizzare JSON errato ed essere in grado di visualizzare dove si trova l'errore

C'è un modo per scoprire in quale posizione nel JSON il parser non è riuscito.

Voglio risolvere questo problema in un'applicazione node.js quindi ti preghiamo di conservare le risposte in quel dominio se possibile.

Quando uso l'oggetto JSON incorporato e il metodo parse per un JSON difettoso, ottengo solo il messaggio di eccezione SyntaxError: Unexpected string. Vorrei sapere dove si è verificato l'errore.

Preferibile sarebbe un JSON.validate(json) che ha restituito risultato ok/errore e la posizione dell'errore. Qualcosa di simile a questo:

var faultyJsonToParse = '{"string":"value", "boolean": true"}'; 
var result = JSON.validate(faultyJsonToParse); 
if (result.ok == true) { 
    console.log('Good JSON, well done!'); 
} else { 
    console.log('The validator found a \'' + result.error + '\' of type \'' + result.errorType + '\' in your JSON near position ' + result.position); 
} 

L'esito desiderato di quanto sopra sarebbe:

The validator found a 'SyntaxError' of type 'Unexpected string' in your JSON near position 35. 
+0

si aspetta un indice in una stringa JSON minified in cui l'errore si è verificato? – Aesthete

+0

Sì, qualcosa del genere. Potrebbe anche essere un percorso per il problema in un JSON di grandi dimensioni, immagino. – javabeangrinder

+0

Yeh .. Forse hanno una lettura di questo .. https://bugzilla.mozilla.org/show_bug.cgi?id=507998 Probabilmente non rispondere alla tua domanda, ma potrebbe dare un po 'di informazioni sul perché questa funzionalità non lo fa esistono in modo nativo – Aesthete

risposta

13

Prova jsonLint:

var faultyJsonToParse = '{"string":"value", "boolean": true"}'; 

try { 
    jsonlint.parse(faultyJsonToParse) 
} catch(e) { 
    document.write('<pre>' + e) 
} 

risultato:

Error: Parse error on line 1: 
...ue", "boolean": true"} 
-----------------------^ 
Expecting 'EOF', '}', ',', ']', got 'undefined' 

(anche se jsonLint è un progetto nodo, può essere utilizzato anche in web: semplicemente afferrare https://github.com/zaach/jsonlint/blob/master/web/jsonlint.js)

Come @ EH9 suggerito, ha senso creare un wrapper attorno al parser standard di JSON per fornire informazioni dettagliate sulle eccezioni:

JSON._parse = JSON.parse 
JSON.parse = function (json) { 
    try { 
     return JSON._parse(json) 
    } catch(e) { 
     jsonlint.parse(json) 
    } 
} 

JSON.parse(someJson) // either a valid object, or an meaningful exception 
2

Il built-in versioni di JSON.parse() non hanno un comportamento coerente. È coerente quando l'argomento è ben formato e incoerente se non lo è. Questo riporta a una specifica incompleta di questa funzione nell'implementazione della libreria JSON originale. La specifica era incompleta perché non definiva un'interfaccia per oggetti di eccezione. E questa situazione porta direttamente alla tua domanda.

Mentre non conosco una soluzione che sia già disponibile in questo momento, la soluzione richiede la scrittura di un parser JSON e il rilevamento delle informazioni sulla posizione per la gestione degli errori. Questo può essere inserito senza problemi nel codice esistente (1) prima invocando la versione nativa, e (2) se la versione nativa genera un'eccezione, invocare la versione sensibile alla posizione (sarà più lenta) lasciare che l'eccezione che il tuo codice standardizzato.

1

Se si utilizza NodeJS, il clarinetto è un parser JSON basato su eventi molto utile che consente di generare messaggi di errore migliori (riga e colonna o l'errore). devo costruire una piccola utility utilizzando clarinet's parser che restituisce:

snippet (string): the actual line where the error happened 
line (number) : the line number of the error 
column (number) : the column number of the error 
message (string): the parser's error message 

Il codice è qui: https://gist.github.com/davidrapin/93eec270153d90581097