J'ai un petit module qui sert de modèle pour mes données. Il se situe entre mes itinéraires et ma base de données pour des données particulières (les données utilisateur dans mon cas).
J'ai besoin de ce module dans mon code de route, appelez la méthode subscribe
dont il dispose et qui souscrit un utilisateur à une liste de diffusion particulière en stockant les données nécessaires dans ma base de données. Yay!
Ma méthode 'subscribe' accepte un courrier électronique et un identifiant de liste de courrier électronique comme paramètres. Il est raisonnable de coder rapidement et de manière bâclée et de mettre un identifiant pour une liste qui n'existe pas. Erreur d'orthographe, vous l'appelez.
Comment puis-je générer une erreur et indiquer le numéro de ligne avec cet identifiant incorrect?
Code de l'intérieur model/user.js:
if (emailLists.indexOf(listId) === -1) {
throw new Error('listId does not exist');
}
Code à l'intérieur de route.js:
user.subscribe('[email protected]', 'knewsletterr', function (error, success) {
if (error) { return sendResponse(500, 'Ahhhhhhh!'); }
if (!error) { return sendResponse(200, 'subscribed'); }
});
En ce moment, je reçois:
/home/.../project/models/user.js:85
if (emailLists.indexOf(listId) === -1) { throw new Error('listId does not exist'); }
^
Error: listId does not exist
Si vous utilisez des rappels de style nœud, la convention n'est pas de throw
, mais vous transmettez l'erreur en tant que premier argument de votre rappel.
// 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)
})
Une sorte de fonction stupide pour utiliser un rappel car il peut être écrit de manière purement synchrone, mais j'espère que cela illustre le motif
Votre fonction est peut-être déjà écrite de manière synchrone - ne vous inquiétez pas, nous pouvons la convertir en une fonction de rappel de style nœud en utilisant quelque chose comme cps2
au dessous de
// 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
Cela dit, la plupart des peuples utilisent les promesses de nos jours. Nous expliquons ci-dessous comment transformer une fonction de rappel de style nœud en une fonction qui renvoie une promesse. Notez que node
fournit cette fonction en tant que util.promisify
, même si je l’ai implémenté ici à des fins de démonstration -
// a conventional function with a node-style callback
const div = (x, y, done) =>
{ if (y === 0)
return done (Error ('cannot divide by zero'))
else
return done (null, x / y)
}
// convert a node-style callback function to a promise-returning function
const promisify = f => (...args) =>
new Promise
( (resolve, reject) =>
f ( ...args
, (err, result) =>
err
? reject (err)
: resolve (result)
)
)
// logging utility for demos below
const logger = p =>
p .then (console.log, console.error)
logger (promisify (div) (6, 3))
// 2
logger (promisify (div) (6, 0))
// Error: cannot divide by zero
Les continuations ne sont que des fonctions pour vous permettre d'écrire ce genre de choses comme bon vous semble - ne pensez pas que vous deviez utiliser des "rappels" ou des promesses de style nœud simplement parce que c'est la seule façon dont vous l'avez vue.
const cont = (...values) =>
k => k (...values)
const div = (x, y) =>
y === 0
? cont (Error ('cannot divide by zero'))
: cont (null, x / y)
const logger = (err, result) =>
err
? console .log ('error:', err.message)
: console .log ('result:', result)
div (6, 3) (logger)
// result: 2
div (6, 0) (logger)
// error: cannot divide by zero
This vous aidera!
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>