Merge pull request #116 from AllenFang/master

prettify and unify the syntax
This commit is contained in:
Bruno Scheufler
2017-12-27 12:51:42 +01:00
committed by GitHub
9 changed files with 75 additions and 66 deletions

View File

@ -722,7 +722,8 @@ This repository is being kept up to date thanks to the help from the community.
🌻 [Robert Manolea](https://github.com/pupix), 🌻 [Robert Manolea](https://github.com/pupix),
🌻 [Xavier Ho](https://github.com/spaxe), 🌻 [Xavier Ho](https://github.com/spaxe),
🌻 [Aaron Arney](https://github.com/ocularrhythm), 🌻 [Aaron Arney](https://github.com/ocularrhythm),
🌻 [Jan Charles Maghirang Adona](https://github.com/septa97) 🌻 [Jan Charles Maghirang Adona](https://github.com/septa97),
🌻 [Allen Fang](https://github.com/AllenFang)

View File

@ -11,8 +11,7 @@ Typically, most of modern Node.JS/Express application code runs within promises
### Code example: these errors will not get caught by any error handler (except unhandledRejection) ### Code example: these errors will not get caught by any error handler (except unhandledRejection)
```javascript ```javascript
DAL.getUserById(1).then((johnSnow) => DAL.getUserById(1).then((johnSnow) => {
{
//this error will just vanish //this error will just vanish
if(johnSnow.isAlive == false) if(johnSnow.isAlive == false)
throw new Error('ahhhh'); throw new Error('ahhhh');
@ -23,11 +22,11 @@ DAL.getUserById(1).then((johnSnow) =>
### Code example: Catching unresolved and rejected promises ### Code example: Catching unresolved and rejected promises
```javascript ```javascript
process.on('unhandledRejection', function (reason, p) { process.on('unhandledRejection', (reason, p) => {
//I just caught an unhandled promise rejection, since we already have fallback handler for unhandled errors (see below), let throw and let him handle that //I just caught an unhandled promise rejection, since we already have fallback handler for unhandled errors (see below), let throw and let him handle that
throw reason; throw reason;
}); });
process.on('uncaughtException', function (error) { process.on('uncaughtException', (error) => {
//I just received an error that was never handled, time to handle it and then decide whether a restart is needed //I just received an error that was never handled, time to handle it and then decide whether a restart is needed
errorManagement.handler.handleError(error); errorManagement.handler.handleError(error);
if (!errorManagement.handler.isTrustedError(error)) if (!errorManagement.handler.isTrustedError(error))
@ -42,16 +41,16 @@ process.on('uncaughtException', function (error) {
> Lets test your understanding. Which of the following would you expect to print an error to the console? > Lets test your understanding. Which of the following would you expect to print an error to the console?
```javascript ```javascript
Promise.resolve(promised value).then(function() { Promise.resolve(promised value).then(() => {
throw new Error(error); throw new Error(error);
}); });
Promise.reject(error value).catch(function() { Promise.reject(error value).catch(() => {
throw new Error(error); throw new Error(error);
}); });
new Promise(function(resolve, reject) { new Promise((resolve, reject) => {
throw new Error(error); throw new Error(error);
}); });
``` ```

View File

@ -18,7 +18,7 @@ DB.addDocument(newCustomer, (error, result) => {
//API route code, we catch both sync and async errors and forward to the middleware //API route code, we catch both sync and async errors and forward to the middleware
try { try {
customerService.addNew(req.body).then(function (result) { customerService.addNew(req.body).then((result) => {
res.status(200).json(result); res.status(200).json(result);
}).catch((error) => { }).catch((error) => {
next(error) next(error)
@ -29,7 +29,7 @@ catch (error) {
} }
//Error handling middleware, we delegate the handling to the centralized error handler //Error handling middleware, we delegate the handling to the centralized error handler
app.use(function (err, req, res, next) { app.use((err, req, res, next) => {
errorHandler.handleError(err).then((isOperationalError) => { errorHandler.handleError(err).then((isOperationalError) => {
if (!isOperationalError) if (!isOperationalError)
next(err); next(err);
@ -47,14 +47,14 @@ function errorHandler(){
this.handleError = function (error) { this.handleError = function (error) {
return logger.logError(err).then(sendMailToAdminIfCritical).then(saveInOpsQueueIfCritical).then(determineIfOperationalError); return logger.logError(err).then(sendMailToAdminIfCritical).then(saveInOpsQueueIfCritical).then(determineIfOperationalError);
} }
}
``` ```
### Code Example Anti Pattern: handling errors within the middleware ### Code Example Anti Pattern: handling errors within the middleware
```javascript ```javascript
//middleware handling the error directly, who will handle Cron jobs and testing errors? //middleware handling the error directly, who will handle Cron jobs and testing errors?
app.use(function (err, req, res, next) { app.use((err, req, res, next) => {
logger.logError(err); logger.logError(err);
if(err.severity == errors.high) if(err.severity == errors.high)
mailer.sendMail(configuration.adminMail, "Critical error occured", err); mailer.sendMail(configuration.adminMail, "Critical error occured", err);

View File

@ -13,22 +13,21 @@ Somewhere within your code, an error handler object is responsible for deciding
//deciding whether to crash when an uncaught exception arrives //deciding whether to crash when an uncaught exception arrives
//Assuming developers mark known operational errors with error.isOperational=true, read best practice #3 //Assuming developers mark known operational errors with error.isOperational=true, read best practice #3
process.on('uncaughtException', function(error) { process.on('uncaughtException', function(error) {
errorManagement.handler.handleError(error); errorManagement.handler.handleError(error);
if(!errorManagement.handler.isTrustedError(error)) if(!errorManagement.handler.isTrustedError(error))
process.exit(1) process.exit(1)
}); });
//centralized error handler encapsulates error-handling related logic //centralized error handler encapsulates error-handling related logic
function errorHandler(){ function errorHandler(){
this.handleError = function (error) { this.handleError = function (error) {
return logger.logError(err).then(sendMailToAdminIfCritical).then(saveInOpsQueueIfCritical).then(determineIfOperationalError); return logger.logError(err).then(sendMailToAdminIfCritical).then(saveInOpsQueueIfCritical).then(determineIfOperationalError);
} }
this.isTrustedError = function(error) this.isTrustedError = function (error) {
{ return error.isOperational;
return error.isOperational; }
}
``` ```

View File

@ -11,11 +11,11 @@ Testing happy paths is no better than testing failures. Good testing code
```javascript ```javascript
describe("Facebook chat", () => { describe("Facebook chat", () => {
it("Notifies on new chat message", () => { it("Notifies on new chat message", () => {
var chatService = new chatService(); var chatService = new chatService();
chatService.participants = getDisconnectedParticipants(); chatService.participants = getDisconnectedParticipants();
expect(chatService.sendMessage.bind({message: "Hi"})).to.throw(ConnectionError); expect(chatService.sendMessage.bind({ message: "Hi" })).to.throw(ConnectionError);
}); });
}); });
``` ```
@ -24,14 +24,19 @@ describe("Facebook chat", () => {
```javascript ```javascript
it("Creates new Facebook group", function (done) { it("Creates new Facebook group", function (done) {
var invalidGroupInfo = {}; var invalidGroupInfo = {};
httpRequest({method: 'POST', uri: "facebook.com/api/groups", resolveWithFullResponse: true, body: invalidGroupInfo, json: true httpRequest({
}).then((response) => { method: 'POST',
//oh no if we reached here than no exception was thrown uri: "facebook.com/api/groups",
}).catch(function (response) { resolveWithFullResponse: true,
expect(400).to.equal(response.statusCode); body: invalidGroupInfo,
done(); json: true
}); }).then((response) => {
}); //oh no if we reached here than no exception was thrown
}).catch(function (response) {
expect(400).to.equal(response.statusCode);
done();
});
});
``` ```

View File

@ -14,12 +14,12 @@ We all loovve console.log but obviously a reputable and persisted Logger like [W
```javascript ```javascript
//your centralized logger object //your centralized logger object
var logger = new winston.Logger({ var logger = new winston.Logger({
level: 'info', level: 'info',
transports: [ transports: [
new (winston.transports.Console)(), new (winston.transports.Console)(),
new (winston.transports.File)({ filename: 'somefile.log' }) new (winston.transports.File)({ filename: 'somefile.log' })
] ]
}); });
//custom code somewhere using the logger //custom code somewhere using the logger
logger.log('info', 'Test Log Message with some parameter %s', 'some parameter', { anything: 'This is metadata' }); logger.log('info', 'Test Log Message with some parameter %s', 'some parameter', { anything: 'This is metadata' });
@ -30,15 +30,19 @@ logger.log('info', 'Test Log Message with some parameter %s', 'some parameter',
```javascript ```javascript
var options = { var options = {
from: new Date - 24 * 60 * 60 * 1000, until: new Date, limit: 10, start: 0, from: new Date - 24 * 60 * 60 * 1000,
order: 'desc', fields: ['message'] until: new Date,
}; limit: 10,
start: 0,
order: 'desc',
fields: ['message']
};
// Find items logged between today and yesterday. // Find items logged between today and yesterday.
winston.query(options, function (err, results) { winston.query(options, function (err, results) {
//callback with results //callback with results
}); });
``` ```

View File

@ -14,19 +14,20 @@ From the blog Ben Nadel, ranked 5 for the keywords “Node.JS error object”
```javascript ```javascript
//throwing an Error from typical function, whether sync or async //throwing an Error from typical function, whether sync or async
if(!productToAdd) if(!productToAdd)
throw new Error("How can I add new product when no value provided?"); throw new Error("How can I add new product when no value provided?");
//'throwing' an Error from EventEmitter //'throwing' an Error from EventEmitter
const myEmitter = new MyEmitter(); const myEmitter = new MyEmitter();
myEmitter.emit('error', new Error('whoops!')); myEmitter.emit('error', new Error('whoops!'));
//'throwing' an Error from a Promise //'throwing' an Error from a Promise
return new promise(function (resolve, reject) { return new Promise(function (resolve, reject) {
Return DAL.getProduct(productToAdd.id).then((existingProduct) =>{ Return DAL.getProduct(productToAdd.id).then((existingProduct) =>{
if(existingProduct != null) if(existingProduct != null)
reject(new Error("Why fooling us and trying to add an existing product?")); reject(new Error("Why fooling us and trying to add an existing product?"));
})
});
``` ```
### Code example Anti Pattern ### Code example Anti Pattern
@ -55,7 +56,7 @@ module.exports.appError = appError;
//client throwing an exception //client throwing an exception
if(user == null) if(user == null)
throw new appError(commonErrors.resourceNotFound, commonHTTPErrors.notFound, "further explanation", true) throw new appError(commonErrors.resourceNotFound, commonHTTPErrors.notFound, "further explanation", true)
``` ```

View File

@ -17,9 +17,9 @@ This approach:
```javascript ```javascript
//Typical mistake 1: saving uploaded files locally in a server //Typical mistake 1: saving uploaded files locally in a server
var multer = require('multer') //express middleware for fetching uploads var multer = require('multer'); //express middleware for fetching uploads
var upload = multer({ dest: 'uploads/' }) var upload = multer({ dest: 'uploads/' });
app.post('/photos/upload', upload.array('photos', 12), function (req, res, next) {}) app.post('/photos/upload', upload.array('photos', 12), function (req, res, next) {});
//Typical mistake 2: storing authentication sessions (passport) in a local file or memory //Typical mistake 2: storing authentication sessions (passport) in a local file or memory
var FileStore = require('session-file-store')(session); var FileStore = require('session-file-store')(session);
app.use(session({ app.use(session({
@ -27,7 +27,7 @@ app.use(session({
secret: 'keyboard cat' secret: 'keyboard cat'
})); }));
//Typical mistake3: storing information on the global object //Typical mistake3: storing information on the global object
Global.someCacheLike.result = {somedata} Global.someCacheLike.result = { somedata };
``` ```
<br/><br/> <br/><br/>

View File

@ -16,10 +16,10 @@ A maintenance endpoint is a plain secured HTTP API that is part of the app code
var heapdump = require('heapdump'); var heapdump = require('heapdump');
router.get('/ops/headump', (req, res, next) => { router.get('/ops/headump', (req, res, next) => {
logger.info(`About to generate headump`); logger.info('About to generate headump');
heapdump.writeSnapshot(function (err, filename) { heapdump.writeSnapshot((err, filename) => {
console.log('headump file is ready to be sent to the caller', filename); console.log('headump file is ready to be sent to the caller', filename);
fs.readFile(filename, "utf-8", function (err, data) { fs.readFile(filename, "utf-8", (err, data) => {
res.end(data); res.end(data);
}); });
}); });