2015-10-12 15 views
5

Ich habe ein kleines Modul, das als ein Modell für meine Daten dient. Es befindet sich zwischen meinen Routen und meiner Datenbank für bestimmte Daten (in meinem Fall Benutzerdaten).Einen Fehler in node.js werfen

Ich benötige dieses Modul in meinem Routencode, rufe die subscribe-Methode auf, die es hat, und abonniert einen Benutzer für eine bestimmte Mailingliste, indem die benötigten Daten in meiner Datenbank gespeichert werden. Yay!

Meine "Subscribe" -Methode akzeptiert eine E-Mail und eine E-Mail-Liste als die beiden Parameter. Es ist vernünftig, dass ich schlampig und schnell kodiere und eine ID für eine Liste einstelle, die nicht existiert. Rechtschreibfehler, Sie nennen es.

Wie kann ich einen Fehler werfen und auf die Zeilennummer mit dieser falschen ID zeigen?

-Code von innen Modell/user.js:

if (emailLists.indexOf(listId) === -1) { 
    throw new Error('listId does not exist'); 
} 

-Code von innen route.js:

user.subscribe('[email protected]', 'knewsletterr', function (error, success) { 
    if (error) { return sendResponse(500, 'Ahhhhhhh!'); } 
    if (!error) { return sendResponse(200, 'subscribed'); } 
}); 

Gerade jetzt, ich bin immer:

/home/.../project/models/user.js:85 
if (emailLists.indexOf(listId) === -1) { throw new Error('listId does not exist'); } 
               ^
Error: listId does not exist 
+0

listId Variable ist nicht in Ihrem Quellcode definiert –

+0

Haha, ich weiß. Ich bin derjenige, der den Fehler wirft. Ich will nur wissen, wie man die passende Zeilennummer und den Dateinamen zusammen mit dem Fehler wirft. – Costa

+1

var e = neuer Fehler ("asdf"); console.log (e.stack) –

Antwort

7

Wenn Sie Knoten-Callbacks verwenden, ist die Konvention nicht zu throw, Sie stattdessen passieren Fehler als erstes Argument an Ihren Rückruf

// divide with callback 
 
function div (x, y, done) { 
 
    if (y === 0) 
 
    return done (Error ('Cannot divide by zero')) 
 
    else 
 
    return done (null, x/y) 
 
} 
 

 
div (6, 3, function (err, result) { 
 
    // *always* check for err 
 
    if (err) 
 
    console.log ('error', err.message, err.stack) 
 
    else 
 
    console.log ('result', result) 
 
})

Eine Art dummer Funktion, um einen Rückruf zu verwenden da es in eine rein synchronen Art und Weise geschrieben werden, aber hoffentlich verdeutlicht dies das Muster


Ihre Funktion könnte bereits in einer synchronen Art und Weise geschrieben werden - keine Sorge tho, wir es mit einem Knoten-Stil umwandeln Callback-Funktion mit so etwas wie cps2 unter

// a "normal" synchronous function that throws an error 
 
const div = (x,y) => 
 
    { 
 
    if (y === 0) 
 
     throw Error ('cannot divide by zero') 
 
    else 
 
     return x/y 
 
    } 
 
    
 
// convert it to a continuation passing style (cps) function 
 
const cps2 = (f, x, y, k) => 
 
    { 
 
    try { 
 
     return k (null, f (x, y)) 
 
    } 
 
    catch (err) { 
 
     return k (err) 
 
    } 
 
    } 
 

 
// logging utility for demos below 
 
const logger = (err, result) => 
 
    { 
 
    if (err) 
 
     console.log ('error:', err.message, err.stack) 
 
    else 
 
     console.log ('result:', result) 
 
    } 
 
    
 
cps2 (div, 6, 3, logger) 
 
// result: 2 
 

 
cps2 (div, 6, 0, logger) 
 
// error: cannot divide by zero


Alle von dieser sagte, sind die meisten Völker Promises heute

const div = (x, y, done) => 
 
    { 
 
    if (y === 0) 
 
     return done (Error ('cannot divide by zero')) 
 
    else 
 
     return done (null, x/y) 
 
    } 
 
    
 
const promisify = f => (...args) => 
 
    new Promise ((resolve, reject) => 
 
    f (...args, (err, result) => 
 
     { 
 
     if (err) 
 
      reject (err) 
 
     else 
 
      resolve (result) 
 
     })) 
 

 
const logp = p => 
 
    p.then (console.log, console.error) 
 
    
 
logp (promisify (div) (6, 3)) 
 
// 2 
 

 
logp (promisify (div) (6, 0)) 
 
// Error: cannot divide by zero


Fortsetzungen verwenden nur Funktionen tho so können Sie diese Art der Sache in irgendeiner Weise schreiben, die Sie mögen - glaube nicht, Sie müssen Knoten-Stil „Callbacks“ oder Versprechungen verwenden nur, weil das der einzige Weg ist, Sie es

const cont = (...values) => 
 
    k => k (...values) 
 

 
const div = (x, y) => 
 
    y === 0 
 
    ? cont (Error ('cannot divide by zero')) 
 
    : cont (null, x/y) 
 

 
const log = (err, result) => 
 
    err 
 
    ? console.log ('error:', err.message) 
 
    : console.log ('result:', result) 
 

 
div (6, 3) (log) 
 
// result: 2 
 

 
div (6, 0) (log) 
 
// error: cannot divide by zero
gesehen haben

+0

Danke, das ist hilfreich! Das ist der erste Ansatz, den ich gemacht habe, aber ich mache drei verschiedene Dinge, je nachdem, was passiert, wenn man jemanden abonniert ("bereits abonniert", "Erfolg", "irgendeinen anderen Fehler"), also war es schwierig, die Dinge konzeptionell zu trennen. Vielleicht sollte ich Fehler nur behandeln, wie die App keine Fehler ausführt, und Ergebnisse für alles andere als Regel behandeln. – Costa

+0

Im Allgemeinen ist 'throw' eine synchrone Methode zur Fehlerbehandlung. Bei der Verwendung von Callbacks wird angenommen, dass es sich um asynchronen Code handelt, wobei "throw" nicht besonders hilfreich ist. Die Idee ist, dass Sie den "Fehler" nicht bei jedem Rückruf in Ihrer Kette abfangen müssen. Wenn Sie einen Fehler in der Mitte nicht behandeln wollen, können Sie ihn einfach "done (err, x)" übergeben. Wenn "err" gleich "null" ist, passiert nichts, aber wenn "err" ein '' ist Fehler, die obige Funktion hat eine Chance, es zu fangen. – naomik

+1

All dies gesagt, das bedeutet nicht, dass dies der beste Weg ist, asynchrone Fehlerbehandlung zu entwerfen. Es ist zufällig die Konvention in Node und daher ist es wahrscheinlich die beste Wahl * wenn * Sie eine App/Lib schreiben, die andere am Ende verwenden werden.Wenn Sie die App nur für sich selbst schreiben, können Sie Ihre Fehlerbehandlung so gestalten, wie Sie es für richtig halten, und einfach die Knotenkonvention verwenden, an die Sie mit anderen Bibliotheken arbeiten. – naomik

2

This wird dir helfen !

var el = document.getElementById('el'); 
 

 
var log = function(val){ 
 
    el.innerHTML+= '<div><pre>' + val + '</pre></div>'; 
 
}; 
 

 

 
try { 
 
    
 
    throw Error('error in code'); 
 
    
 
} catch (e) { 
 

 
    log(e.message); 
 
    log(e.fileName); 
 
    log(e.lineNumber); 
 
    log(e.stack); 
 

 
};
<div id='el'></div>

+0

Danke, ich habe diese MDN-Seite gelesen. Es ist der node.js-Stack-Trace, mit dem ich Probleme habe. Ich gebe zu, ich bin zu diesem Zeitpunkt etwas verwirrt. – Costa

+1

so: https://www.joyent.com/developers/node/design/errors#appendix-conventional-properties-for-error-objects – Anonymous0day