2016-08-18 5 views
1

Ich habe einen sehr einfachen Migrationscode, der so aussieht. Es entfernt die Tabelle, erstellt die Tabelle und sät diese mit einigen Daten.Korrekte Fehlerbehandlung mit NodeJS/Express

this.knex.schema.dropTable(this.tableName) 
.catch((err) => console.log(err)) 
.then(() => { 
    this.knex.schema.createTable(this.tableName, function(table) { 
     table.increments("id").primary(); 
     table.string("name"); 
     table.integer("parent_id").unsigned().default(0); 
    }) 
    .catch((err) => console.log(err)) 
    .then(() => { 
     this.categories.forEach((category) => { 
      Category.create(category) 
      .catch((err) => console.log(err)) 
      .then((category) => console.log(category.get("name") + " seeded.")) 
     }); 
    }); 
}); 

Wie Sie sehen können, gibt es 3x .catch((err) => console.log(err)) Kette auf dem Code.

Gerade jetzt habe ich Bugsnag in meine Anwendung integriert und ich möchte sicherstellen, dass ich alle Ausnahmen/Fehler auf Bugsnag ordnungsgemäß protokolliere, damit ich alle Bugs beheben kann. Im Moment kann ich sie jedoch nur in die Konsole einspielen. Noch schlimmer, ich wiederhole mich selbst und dupliziere die Logik in jedem catch Block.

Ich denke an so etwas wie dies zu tun:

.catch((err) => ErrorHandler.add(err)) 

class ErrorHandler { 

    add(err) { 
     // Notify Bugsnag 
     // Log it to console 
    } 

} 

, dass ein anderes Problem abrings. Was passiert, wenn ich vergessen habe, catch Methoden hinzuzufügen ... dann wird es immer noch nicht funktionieren.

Gedanken über so etwas wie dies zu tun, auch:

// Change exception behaviour so whenever they are called, they raise an `onException` event 
app.listen("onException", (err) => { 
    // Notify Bugsnag 
    // Log error to console 
}); 

So kann ich alle Fehler fangen und meinen Code trocken, aber ich bin nicht sicher, ob Knoten Haken Ausnahmen unterstützt.

Was würden Sie in meinem Fall tun und welche Art von Ansatz sollte ich nehmen? Ich möchte sicherstellen, dass alle Fehler ordnungsgemäß an Bugsnag gesendet werden.

Antwort

1

Vor allem, gibt this.knex.schema.createTable ein Versprechen zurück? (Falls nicht, können Sie es immer konvertieren ein Versprechen zurück) Wenn so könnte man diese Logik in einem wenig sauberen Weise schreiben, wie:

this.knex.schema.dropTable(this.tableName) 
.then((...) => { 
    ... 
    return this.knex.schema.createTable(...) 
}) 
.then((...) => { 
... // do whatever you are doing with table object 
    return Promise.all(map and do whatever you are doing with categories) 
}) 
.then(() => { 
    // log that everything went well with seeding 
}) 
.catch((err) => { 
    // single catch block to handle errors from this promise chain 
}) 

Promise.all wird abgelehnt Versprechen zurück, wenn Versprechen von Array ablehnen, wenn Sie finden, dass dies Ihre Bedürfnisse nicht Suite können Sie .reflect() von drossel verwenden (etwas, das einheimische Versprechen Unterstützung in Knoten muß nicht haben, http://bluebirdjs.com/docs/api/reflect.html)

Zweitens statt console.log (console.error oder was auch immer) Sie betrachten können, zu verwenden, etwas wie Bunyan, https://github.com/trentm/node-bunyan

Drittens, in der Regel braucht man immer Ihre Anwendung gegen uncaughtException, wie

process.on('uncaughtException', (err) => { 
    ... 
}) 

zu verteidigen Was passiert, wenn ich das Hinzufügen Fangmethoden

Aus meiner Sicht vergessen, die Fehler im Code sein würde und Sie müssen sich bewusst sein davon. Es ist das gleiche wie Sie vergessen, Fehler in Rückruf zu handhaben, wie zum Beispiel:

doSomething((err, data) => { 
    // do something with data without checking against err 
}) 

So gleiche Frage gestellt werden könnte, What if I forget to check against err, auch um es einfach auszudrücken sind Sie nicht die Fehlerbehandlung. Als Faustregel gilt, dass nicht nur sonnige Tagesszenarien getestet werden, wie alles gut gelaufen ist. Testen Sie verschiedene Szenarien in Ihrem Code, einschließlich Regentageszenarien, in denen etwas geworfen wird, und stellen Sie sicher, dass Sie es richtig handhaben.

Auch gibt es noch eine Sache, von der Sie profitieren können, Sie erwähnten Express in Ihrer Frage.Sie können globale Fehler-Handler registrieren, die Sie nach all Ihre Routen wie definieren müssen:

app.use((err, req, res, next) => { 
    ... 
}) 

Damit aus jeder Route, die Sie Ihren Fehler über return next(err) zu diesem Handler (falls einige spezielle Fehlerbehandlungslogik nicht passieren kann, ist, benötigt, spezifisch für einen bestimmten Endpunkt), einen Ort zu gewährleisten, von dem Sie Ihre Fehler wie Log-Fehler behandeln und 500 mit einer Nachricht oder was auch immer zurückgeben können. https://expressjs.com/en/guide/error-handling.html

+0

Danke für die erstaunliche Antwort. Wenn createTable kein Versprechen zurückgibt, wie kann ich es konvertieren, um ein Versprechen zurückzugeben? Was genau ist Bluebird und wie versteht es die Vervollständigung einer Array-Map? Im Moment ist es nur ein Haufen verschiedener 'save (...). Dann (...)' Versprechungen. Ich denke, ich muss bald etwas über Versprechen lesen. Kannst du irgendetwas dazu vorschlagen? – Aris

+0

Ihre Vermutung ist richtig, Sie sollten zuerst mit Versprechen vertraut werden, etwas, das wirklich helfen kann: https://pouchdb.com/2015/05/18/we-have-a-problem-with-promises.html – Srle

+0

Ich readed es. Es beantwortet die meisten meiner Fragen. Ich bin mir aber nicht sicher, wie ich das promi- tieren kann: 'this.knex.schema.createTable'. Wenn ich in Zukunft etwas versprechen muss, das kein Versprechen gibt, wie kann ich es dann tun? Überschreiben Sie die Methode und geben Sie 'Promise.something()' zurück? – Aris