2016-11-23 2 views
0

Am Ende meiner server.js Datei ich den folgenden Code haben:Express.js Fehlerbehandlung funktioniert nicht

app.use(logErrors); 

function logErrors (err: Error, req: Request, res: Response, next: NextFunction) { 
    console.log(err); 
    mongoDal.log(err.message, err); 
    next(err); 
} 

aber dieser Code nicht erreicht wird erhalten, wenn ein Fehler auftritt.

Ich habe auch die Node.js Fehlerbehandlungsfunktion, die nicht erreicht bekommt entweder:

process.on('uncaughtException', function (err: Error) { 
    try { 
     console.log(err); 
     mongoDal.log(err.message, err); 
    } catch (err) { 

    } 
}); 

Dies ist der Code, der den Fehler erzeugt:

app.get('/test_feature', function (req: Request, res: Response) { 
    makeError(); 

    res.send("Done"); 
}); 

function makeError(){ 
    throw new Error("asdasdad"); 
} 

BTW der Fehler tut in die Konsole geschrieben werden (aber nicht durch eine Funktion von mir), und die App stürzt nicht ab.

Was ich versuche zu machen, ist eine generische Lösung, die jede unbehandelte Ausnahme an einem Ort abfängt.

Was mache ich falsch?

+0

Wie definieren Sie Ihre Anfragen ?? app.get (req, res) ??? –

+0

@LucasKatayama ja – Alon

+1

Express verfügt bereits über einen Standardfehlerhandler, der wahrscheinlich den Fehler protokolliert. Meine Vermutung ist, dass Sie Ihren Error-Handler an einem Punkt installieren, wo es nicht die allerletzte Middleware ist, aber ich kann nicht sicher sagen, ohne zu wissen, wie Ihre App strukturiert ist (ist 'server.js' der App-Einstiegspunkt, oder Starten Sie die App durch eine andere Datei?) – robertklep

Antwort

1

Unten ist das kurze Arbeitsbeispiel mit Handhabung für 3 Arten von Fehlern: 1) übergeben an next() Handler, 2) throw-ed in Route-Handler, 3) unbehandelter Fehler innerhalb Callback einer Funktion von Route Handler aufgerufen.

(1) und (2) werden mit benutzerdefinierten Fehler Middleware-Handler (A) erfasst und (3) wird von uncaughtException Handler (B) erfasst.

Express verfügt über einen eigenen Fehlerhandler, der einen Fehler ausgibt, wenn er die Steuerung über die Kette next() aufruft (d. H. Wenn kein benutzerdefinierter Fehlerhandler vorhanden ist oder das Steuerelement den Befehl weitergibt, next(err, req, res, next)). Deshalb erhalten Sie immer noch eine Fehlermeldung in der Konsole, selbst wenn der yeyr-Handler keine Trigger ist.

Wenn Sie versuchen, das Beispiel für Fälle (1) und (2) auszuführen, werden die Fehlerausgaben zweimal angezeigt - von benutzerdefiniertem Handler (A) und standardmäßig Express-Fehlerhandler.

'use strict'; 

var express = require('express'); 
var app = express();  

var server = app.listen(8080, function() { 
    console.log('* Server listening at ' + server.address().address + ':' + server.address().port); 
}); 

// Example 1: Pass error in route handler to next() handler 
app.use('/1', function(req, res, next) { 
    console.log('* route 1'); 
    next(new Error('* route 1 error')); 
}); 

// Example 2: throw the error in route handler 
app.use('/2', function(req, res, next) { 
    console.log('* route 2'); 
    throw new Error('route 2 error'); 
}); 

// Example 3: unhandled error inside some callback function 
app.use('/3', function(req, res, next) { 
    console.log('* route 3'); 
    setTimeout(function(){ 
    throw new Error('route 3 error'); 
    }, 500); 
}); 

// Error handler A: Express Error middleware 
app.use(function(err, req, res, next) { 
    console.log('**************************'); 
    console.log('* [Error middleware]: err:', err); 
    console.log('**************************'); 
    next(err); 
}); 

// Error handler B: Node's uncaughtException handler 
process.on('uncaughtException', function (err) { 
    console.log('**************************'); 
    console.log('* [process.on(uncaughtException)]: err:', err); 
    console.log('**************************'); 
}); 

Node-Version: v7.2.0

Typischer Fehler ist Fehler-Handler vor Routendefinitionen zu platzieren, sondern nach Ihrer Beschreibung, die nicht der Fall ist.

Um das Problem zu finden, können Sie versuchen, Ihren eigenen Code auf die gleiche Größe wie meins zu reduzieren, und ich denke, das Problem wird offensichtlich.


UPDATE

Außerdem, wenn ich versuche, den Code, den Sie zur Verfügung gestellt (mit trivialen Änderungen) zu laufen, es funktioniert für mich:

'use strict'; 

var express = require('express'); 
var app = express(); 

var server = app.listen(8080, function() { 
    console.log('* Server listening at ' + server.address().address + ':' + server.address().port); 
}); 

//process.on('uncaughtException', function (err: Error) { 
process.on('uncaughtException', function (err) { 
    try { 
    console.log('*** uncaughtException:', err); 
    //mongoDal.log(err.message, err); 
    } catch (err) { 

    } 
}); 

//app.get('/test_feature', function (req: Request, res: Response) { 
app.get('/test_feature', function (req, res) { 
    makeError(); 
    res.send("Done"); 
}); 

function makeError(){ 
    throw new Error("asdasdad"); 
} 

app.use(logErrors); 

//function logErrors (err: Error, req: Request, res: Response, next: NextFunction) { 
function logErrors (err, req, res, next) { 
    console.log('*** logErrors:', err); 
    //mongoDal.log(err.message, err); 
    next(err); 
} 

Das Ergebnis ist (Stack-Traces werden abgeschnitten) :

* Server listening at :::8080 
*** logErrors: Error: asdasdad 
    at makeError (/home/alykoshin/sync/al-projects/dev/nmotw/400-express-error-handling/main-stackoverflow.js:32:9) 
........... 
Error: asdasdad 
    at makeError (/home/alykoshin/sync/al-projects/dev/nmotw/400-express-error-handling/main-stackoverflow.js:32:9) 
........... 

Sie am Anfang der ouput von logErrors Handler sehen kann und dann t Er gibt den Standard-Express-Fehlerhandler aus.

+0

Ein anderer Vorschlag ist, dass Sie einen anderen Fehlerhandler vor Ihrem haben, der die Fehlermeldung ausgibt, aber das Steuerelement mit 'next (err)' nicht weitergibt – alykoshin

0

denke ich, das Problem auf den Routing-Definitionen ist

Wie Sie sagten, Sie sind mit dieser

app.get('/test_feature', function (req, res) { 
    throw new Error("asdasdad"); 
    res.send("Done"); 
}); 

Versuchen Sie es mit dieser:

app.get('/test_feature', function (req, res, next) { 
    next(new Error("asdasdad")); 
}); 

Und dann res.send auf das setzen Error Handler ...

Warum?

Ich denke, einen Fehler innerhalb der Funktion zu werfen stoppt die Anfrage-Kette ... So erreicht es nicht die Ende und dann Ihre Fehlerbehandlung. Wenn Sie als zweite Möglichkeit schreiben ... Sie den Fehler weiterleiten ... und dann Ihren Handler erreicht ...

+0

Ich habe meinen Code vereinfacht. Ich bekomme tatsächlich einen Fehler von einer Funktion, die ich anrufe. Ich kann es mit einem try/catch-Block abfangen, aber ich möchte keinen try/catch-Block zu jeder app.get-Funktion hinzufügen. Ich möchte eine generische Lösung, die alle unbehandelten Ausnahmen an einem Ort abfängt. – Alon

+0

Ich habe meine Frage neu formuliert, um sie klarer zu machen – Alon

+0

Probieren Sie diese http://stackoverflow.com/questions/19690756/how-cani-i-wrap-every-express-js-request-in-a-domain- oder- trycatch –

0

Wenn Sie die globale uncaughtException ausführen möchten, benötigen Sie einen Fehler an einem Ort zu werfen, wo niemand ist ansteckend, wie folgt aus:

app.get('/test_feature', function (req: Request, res: Response) { 
    setTimeout(function() { throw new Error('oops'); }, 1000); 

    res.send("Done"); 
}); 

Ein synchroner throw innerhalb eines Handlers durch Eil gefangen wird, keine uncaughtException passiert überhaupt als wurde gefangen.

Und nach http://expressjs.com/en/guide/error-handling.html, eine Fehlerbehandlung Middleware nach Ihre Routen und andere Middle definiert.

app.get('/test_feature', function (req: Request, res: Response) { 
    makeError(); 

    res.send("Done"); 
}); 

app.use(logErrors) 

Wenn Sie die falsche Bestellung erhalten, gäbe es keine Fehlerbehandlung werden aufgerufen, wenn etwas geworfen wird.

Verwandte Themen