Error: Import failed zeigt auf eine Zeile, die einen Fehler erstellt. Dort sehen Sie, wie die Anwendung einen Fehler meldet. Um den tatsächlichen Fehlschlag zu finden, folgen Sie dem angehängten cause zum Parser und prüfen Sie dessen Eingabe.
Laden Sie die vollständige JavaScript-Stacktrace-Übung herunter, entpacken Sie sie und wechseln Sie nach read-javascript-stack-trace. Sie nutzt lokale Dateien und eingebaute Node-Module, ohne Installation oder Netzwerkanfragen. Das Beispiel wurde für diese Anleitung erstellt. Sein Importschritt liest und parst Datensätze, ohne sie zu speichern. Alle Befehle unten wurden mit Node.js 22.22.1 ausgeführt; verwenden Sie Node.js 22 oder neuer.
Die drei Quelldateien bilden einen kleinen Untersuchungspfad:
| Datei | Aufgabe | Zu prüfende Hinweise |
|---|---|---|
run.mjs |
Wählt die Eingabe und wartet auf den Import | Eingabedateiname, Ergebnis, Exit-Status |
importer.mjs |
Liest die Datei, ruft den Parser auf, umhüllt Fehler | try-Block und abgefangenes cause |
parser.mjs |
Übergibt Text an JSON.parse |
Parseraufruf und übergebener Text |
Die fehlerhafte Eingabe ausführen und beide Stacks behalten
node run.mjs with-cause
Dieser Befehl soll mit Status 1 fehlschlagen. Die Ausgabe unten kombiniert stdout und stderr; nur der absolute Verzeichnispräfix wurde durch file:///lab/ ersetzt. Dateinamen, Zeilen, Spalten und Fehlertext stammen aus dem dokumentierten Lauf.
Input: records.bad.json
Error: Import failed
at importRecords (file:///lab/importer.mjs:10:19)
at async file:///lab/run.mjs:14:19
Caused by:
SyntaxError: Expected double-quoted property name in JSON at position 29 (line 2 column 28)
at JSON.parse (<anonymous>)
at parseRecords (file:///lab/parser.mjs:2:15)
at importRecords (file:///lab/importer.mjs:7:12)
at async file:///lab/run.mjs:14:19
run.mjs gibt error.stack und error.cause.stack getrennt aus. Der erste Stack gehört zum Wrapper, der zweite zum abgefangenen SyntaxError. Bewahren Sie diese Unterscheidung beim Kopieren eines Fehlerberichts. Ein Logger, der nur die äußere Meldung speichert, verwirft hier die meisten nützlichen Hinweise.
In importer.mjs:10:19 bezeichnen die letzten Zahlen Quellzeile und Spalte. In der Parsermeldung bezieht sich „line 2 column 28“ auf die JSON-Eingabe. Das sind zwei Koordinatensysteme. Ordnen Sie jede Stelle der passenden Datei oder dem Wert zu und nutzen Sie dieselbe Quellcodeversion wie beim Trace.
Die Erstellungszeile öffnen, dann den catch-Zweig lesen
Hier ist die vollständige importer.mjs aus dem Download:
import { readFile } from 'node:fs/promises';
import { parseRecords } from './parser.mjs';
export async function importRecords(input, { preserveCause = true } = {}) {
try {
const text = await readFile(input, 'utf8');
return parseRecords(text);
} catch (cause) {
const options = preserveCause ? { cause } : undefined;
const error = new Error('Import failed', options);
throw error;
}
}
Zeile 10 erstellt den Wrapper. Zeile 11 wirft das vorhandene Objekt. Der äußere Stack beginnt bei Zeile 10, weil Node die Position von new Error() aufzeichnet. Ein späteres Werfen desselben Objekts verschiebt diese gespeicherte Position nicht. Die Node.js-22-Fehlerdokumentation beschreibt dies.
Auch der try-Block zählt: Sowohl readFile als auch parseRecords können fehlschlagen, beide erhalten dieselbe äußere Meldung. „Import failed“ allein verrät den betroffenen Zweig nicht. Der Test einer fehlenden Datei erhält etwa ENOENT als Ursache statt SyntaxError.
Der Ursache zum Parser und seiner tatsächlichen Eingabe folgen
Der Ursachen-Stack nennt zuerst JSON.parse. Gehen Sie zum ersten überprüfbaren eigenen Frame: parser.mjs:2:15.
export function parseRecords(text) {
return JSON.parse(text);
}
Verfolgen Sie dann text zurück zu readFile(input, 'utf8'). run.mjs hat records.bad.json gewählt, dessen vollständiger Inhalt lautet:
[
{"id": "tea", "count": 2,}
]
Das Komma nach 2 lässt den Parser einen weiteren Eigenschaftsnamen erwarten. Stattdessen findet er } an der gemeldeten Eingabeposition. Damit haben Sie Eingabe, konkrete Operation und reproduzierbaren Fehler. Die Erstellungszeile des Wrappers war der Einstieg in die Untersuchung; eine andere Meldung würde dieses JSON nicht ändern.
new Error(message, { cause }) hält den abgefangenen Wert am neuen Fehler zugänglich. Node hat die Option in 16.9.0 eingeführt; sie ist für die hier genutzte Version 22.22.1 dokumentiert. Der Wert kann beliebig sein, daher sollte allgemeine Fehlerbehandlung seinen Typ vor dem Lesen von .stack prüfen. Der Ausgabecode hier prüft instanceof Error. Siehe Nodes Referenz zu error.cause.
Die Ursache entfernen und den Informationsverlust sehen
node run.mjs without-cause
Auch dieser Befehl endet mit Status 1. Dieselbe Eingabe scheitert weiterhin, doch die Ausgabe endet nun so:
Error: Import failed
at importRecords (file:///lab/importer.mjs:10:19)
at async file:///lab/run.mjs:14:19
Cause: unavailable
Dieser Modus übergibt keine cause-Option an new Error. Der Wrapper trägt den Parserfehler nicht mehr. Sein Stack kann die verworfene Eingabeposition nicht zurückbringen und den Fehler nicht vom fehlenden Dateipfad unterscheiden. Nötig wäre eine weitere Beobachtung, etwa eine lokale Reproduktion mit erhaltener Originalursache.
Das Beibehalten von cause verbessert die Untersuchung, repariert aber die Eingabe nicht: with-cause scheitert weiterhin, wie der erste Befehl zeigt.
Asynchrone Frames als Hinweise nutzen und Lücken im Code schließen
Beide dokumentierten Stacks enthalten at async .../run.mjs:14:19, den wartenden Aufrufer. Beim Parserfehler ist readFile bereits abgeschlossen. Seine Arbeit fehlt im Trace, obwohl sein Ergebnis den Parser versorgt hat.
Die V8-Dokumentation zu asynchronen Stacks beschreibt die Rekonstruktion um await und ausgewählte Promise-Operationen wie Promise.all() und Promise.any(). Diese Frames zeigen bestimmte asynchrone Beziehungen, aber keine vollständige Historie von Callbacks, Timern oder I/O. Ein fehlender Frame beweist nicht, dass die Arbeit nie ausgeführt wurde.
Wortlaut von SyntaxError und verfügbare Frames können je nach Node-/V8-Version variieren. Öffnen Sie anhand der angezeigten Stellen den passenden Code; betrachten Sie dieses Protokoll nicht als universelles Stackformat. Die Tests prüfen nützliche Fehlereigenschaften und Anwendungsframes, nicht die gesamte Stack-Zeichenfolge.
Die Wiederholungs-Hypothese an der Eingabe prüfen
Betrachten Sie die Aussage „Das ist ein vorübergehendes Netzwerkproblem; Wiederholen sollte helfen.“ Sie dient als zu prüfende Lehrhypothese, nicht als Zitat eines KI-Systems oder realen Vorfalls.
Der Trace zeigt SyntaxError bei JSON.parse. Der Quellcode zeigt Bytes aus einer lokalen Datei als Eingabe. Die Übung enthält keine Netzwerkoperation, und drei Versuche mit unveränderten fehlerhaften Bytes schlagen alle fehl. Die vorgeschlagene Erklärung hat hier keine Belege.
Führen Sie nun die korrigierte Fixture aus, aus der nur das abschließende Komma entfernt wurde:
node run.mjs fixed
Sie endet mit Status 0 und gibt aus:
Input: records.fixed.json
Parsed records: [{"id":"tea","count":2}]
Führen Sie anschließend die Regressionstests aus:
node --test importer.test.mjs
Alle neun Tests bestehen. Sie prüfen erhaltene Parserursache, verlustbehafteten Wrapper, wiederholten Fehler bei unveränderter Eingabe, korrigierte Eingabe, fehlende Datei, Erstellung gegenüber späterem Werfen und die drei CLI-Modi. Die beiden scheiternden Demonstrationen sind erwartete Fehler, keine fehlgeschlagenen Regressionstests.
Damit ist die Erklärung für diese lokalen Bytes belegt. Verfolgen Sie in einem echten Importer weiter, wer den ungültigen Text erzeugt hat, bevor Sie seinen Ursprung beurteilen. Die Übung prüft JSON-Syntax und Beispielergebnis; sie validiert kein Datensatzschema und speichert keinen Import.
Den umgebenden Code in Yenpo lesen, im Terminal prüfen
Öffnen Sie den entpackten Ordner in Yenpo und finden Sie mit der Codelese-Anleitung importer.mjs, parser.mjs und die gewählte Eingabe. Beginnen Sie an den gemeldeten Zeilen und lesen Sie dann den vollständigen catch-Zweig sowie den Aufrufer, der input liefert.
Mit eingerichtetem Modell hilft Yenpos AI Reader bei der Untersuchung. Eine gezielte Frage wäre:
Verfolge diesen Import-failed-Fehler von seiner Erstellungszeile über cause bis zur Eingabe von JSON.parse. Nenne Dateien und Zeilen. Trenne das, was der Stack zeigt, vom durch Code Belegten und dem, was noch einen Terminallauf benötigt. Prüfe, ob Wiederholen die Bytes dieses Beispiels ändern kann.
Führen Sie die Befehle im Terminal aus und vergleichen Sie die Ausgabe mit der Erklärung.