2015-10-12 14 views
5

Mam niewielki moduł, który działa jako model dla moich danych. Znajduje się pomiędzy moimi trasami a moją bazą danych dla konkretnych danych (dane użytkownika w moim przypadku).Zgłaszanie błędu w pliku node.js

Wymagam tego modułu w swoim kodzie trasy, zadzwonię na jego numer subscribe, który subskrybuje użytkownika do konkretnej listy mailingowej, przechowując potrzebne dane w mojej bazie danych. Yay!

Moja metoda "zapisz się" akceptuje wiadomość e-mail i identyfikator listy e-mail jako dwa parametry. Rozsądne jest, że będę kodować niechlujnie i szybko i wstawić identyfikator dla listy, która nie istnieje. Błąd pisowni, wymieniasz go.

Jak mogę podać błąd i wskazać numer linii o tym niepoprawnym identyfikatorze?

Kod z wnętrza modelu/user.js:

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

Kod z wewnątrz route.js:

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

Teraz dostaję:

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

Zmienna listId nie jest zdefiniowana w kodzie źródłowym –

+0

Haha, wiem. Jestem tym, który rzuca błąd. Chcę tylko wiedzieć, jak wyrzucić odpowiedni numer linii i nazwę pliku wraz z błędem. – Costa

+1

var e = new Error ("asdf"); console.log (e.stack) –

Odpowiedz

7

Jeśli używasz callbacków węzeł stylu, konwencja nie ma throw, zamiast przekazać wam błąd jako pierwszy argument do wywołania zwrotnego

// 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) 
 
})

Rodzaj głupiej funkcji korzystania z oddzwaniania ponieważ może być napisany w sposób czysto synchroniczny, ale mam nadzieję, że ten ilustruje wzór


Twoja funkcja może już być napisane w sposób synchroniczny - nie martw Chciaż, możemy przekonwertować go do węzła stylu funkcja oddzwaniania przy użyciu coś cps2 poniżej

// 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


All o powiedział, że większość ludzie używają Promises obecnie

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


Kontynuacje są tylko funkcje tho więc można napisać tego rodzaju rzeczy w jakikolwiek sposób, że chcesz - nie sądzę trzeba użyć node-style „zwrotnych” lub Promises tylko dlatego, że to jedyny sposób, widzieliście go

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

+0

Dzięki, to jest pomocne! To jest pierwsze podejście, które podjąłem, ale robię trzy różne rzeczy w zależności od tego, co się dzieje, gdy subskrybujesz kogoś ("już zasubskrybowałeś", "sukces", "jakiś inny błąd"), więc trudno było oddzielić koncepcje od rzeczy. Może powinienem traktować błąd, ponieważ aplikacja nie będzie uruchamiać błędów i z reguły traktować wyniki dla wszystkiego innego. – Costa

+0

Ogólnie rzecz biorąc, 'throw' jest metodą synchroniczną do obsługi błędów. Używając wywołań zwrotnych, zakłada się, że masz do czynienia z kodem asynchronicznym, w którym 'throw' nie będzie szczególnie pomocny. Pomysł polega na tym, że nie musisz łapać 'err' w każdym wywołaniu zwrotnym w twoim łańcuchu. Jeśli nie chcesz obsłużyć błędu w środku, możesz po prostu przekazać go dalej 'done (err, x);' Jeśli 'err' ma wartość' null', nic się nie stanie, ale jeśli 'err' jest' Błąd ", powyższa funkcja ma szansę go złapać. – naomik

+1

Wszystko to powiedziawszy, nie oznacza to, że jest to * najlepszy * sposób zaprojektowania obsługi błędów asynchronicznych. Tak się składa, że ​​jest to konwencja w węźle i dlatego jest to prawdopodobnie najlepszy wybór, jeśli * piszesz aplikację/bibliotekę, z której inni będą korzystać.Jeśli sam piszesz aplikację, możesz zaprojektować obsługę błędów, ale uważasz, że jest dla ciebie najlepszy i po prostu użyj konwencji węzła, w której łączysz się z innymi bibliotekami. – naomik

2

This pomoże Ci !

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

Dziękuję, przeczytałem tę stronę MDN. Jest to ślad stosu węzła node.js, z którym prawdopodobnie mam problemy. Przyznaję, jestem nieco zdezorientowany w tym momencie. – Costa

+1

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