mirror of
https://github.com/goldbergyoni/nodebestpractices.git
synced 2025-10-27 02:44:28 +08:00
Use simple quotes everywhere
This commit is contained in:
@ -13,7 +13,7 @@ Without one dedicated object for error handling, greater are the chances of impo
|
|||||||
// DAL layer, we don't handle errors here
|
// DAL layer, we don't handle errors here
|
||||||
DB.addDocument(newCustomer, (error, result) => {
|
DB.addDocument(newCustomer, (error, result) => {
|
||||||
if (error)
|
if (error)
|
||||||
throw new Error("Great error explanation comes here", other useful parameters)
|
throw new Error('Great error explanation comes here', other useful parameters)
|
||||||
});
|
});
|
||||||
|
|
||||||
// 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
|
||||||
@ -45,7 +45,7 @@ app.use(async (err, req, res, next) => {
|
|||||||
// DAL layer, we don't handle errors here
|
// DAL layer, we don't handle errors here
|
||||||
DB.addDocument(newCustomer, (error: Error, result: Result) => {
|
DB.addDocument(newCustomer, (error: Error, result: Result) => {
|
||||||
if (error)
|
if (error)
|
||||||
throw new Error("Great error explanation comes here", other useful parameters)
|
throw new Error('Great error explanation comes here', other useful parameters)
|
||||||
});
|
});
|
||||||
|
|
||||||
// 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
|
||||||
|
|||||||
@ -11,7 +11,7 @@ Distinguishing the following two error types will minimize your app downtime and
|
|||||||
|
|
||||||
```javascript
|
```javascript
|
||||||
// marking an error object as operational
|
// marking an error object as operational
|
||||||
const myError = new Error("How can I add new product when no value provided?");
|
const myError = new Error('How can I add new product when no value provided?');
|
||||||
myError.isOperational = true;
|
myError.isOperational = true;
|
||||||
|
|
||||||
// or if you're using some centralized error factory (see other examples at the bullet "Use only the built-in Error object")
|
// or if you're using some centralized error factory (see other examples at the bullet "Use only the built-in Error object")
|
||||||
@ -25,7 +25,7 @@ class AppError {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
throw new AppError(errorManagement.commonErrors.InvalidInput, "Describe here what happened", true);
|
throw new AppError(errorManagement.commonErrors.InvalidInput, 'Describe here what happened', true);
|
||||||
|
|
||||||
```
|
```
|
||||||
</details>
|
</details>
|
||||||
@ -52,7 +52,7 @@ export class AppError extends Error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// marking an error object as operational (true)
|
// marking an error object as operational (true)
|
||||||
throw new AppError(errorManagement.commonErrors.InvalidInput, "Describe here what happened", true);
|
throw new AppError(errorManagement.commonErrors.InvalidInput, 'Describe here what happened', true);
|
||||||
|
|
||||||
```
|
```
|
||||||
</details>
|
</details>
|
||||||
|
|||||||
@ -10,11 +10,11 @@ Testing ‘happy’ paths is no better than testing failures. Good testing code
|
|||||||
<summary><strong>Javascript</strong></summary>
|
<summary><strong>Javascript</strong></summary>
|
||||||
|
|
||||||
```javascript
|
```javascript
|
||||||
describe("Facebook chat", () => {
|
describe('Facebook chat', () => {
|
||||||
it("Notifies on new chat message", () => {
|
it('Notifies on new chat message', () => {
|
||||||
const chatService = new chatService();
|
const 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,11 +24,11 @@ describe("Facebook chat", () => {
|
|||||||
<summary><strong>Typescript</strong></summary>
|
<summary><strong>Typescript</strong></summary>
|
||||||
|
|
||||||
```typescript
|
```typescript
|
||||||
describe("Facebook chat", () => {
|
describe('Facebook chat', () => {
|
||||||
it("Notifies on new chat message", () => {
|
it('Notifies on new chat message', () => {
|
||||||
const chatService = new chatService();
|
const 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);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
```
|
```
|
||||||
@ -40,11 +40,11 @@ describe("Facebook chat", () => {
|
|||||||
<summary><strong>Javascript</strong></summary>
|
<summary><strong>Javascript</strong></summary>
|
||||||
|
|
||||||
```javascript
|
```javascript
|
||||||
it("Creates new Facebook group", () => {
|
it('Creates new Facebook group', () => {
|
||||||
const invalidGroupInfo = {};
|
const invalidGroupInfo = {};
|
||||||
return httpRequest({
|
return httpRequest({
|
||||||
method: 'POST',
|
method: 'POST',
|
||||||
uri: "facebook.com/api/groups",
|
uri: 'facebook.com/api/groups',
|
||||||
resolveWithFullResponse: true,
|
resolveWithFullResponse: true,
|
||||||
body: invalidGroupInfo,
|
body: invalidGroupInfo,
|
||||||
json: true
|
json: true
|
||||||
@ -61,12 +61,12 @@ it("Creates new Facebook group", () => {
|
|||||||
<summary><strong>Typescript</strong></summary>
|
<summary><strong>Typescript</strong></summary>
|
||||||
|
|
||||||
```typescript
|
```typescript
|
||||||
it("Creates new Facebook group", async () => {
|
it('Creates new Facebook group', async () => {
|
||||||
let invalidGroupInfo = {};
|
let invalidGroupInfo = {};
|
||||||
try {
|
try {
|
||||||
const response = await httpRequest({
|
const response = await httpRequest({
|
||||||
method: 'POST',
|
method: 'POST',
|
||||||
uri: "facebook.com/api/groups",
|
uri: 'facebook.com/api/groups',
|
||||||
resolveWithFullResponse: true,
|
resolveWithFullResponse: true,
|
||||||
body: invalidGroupInfo,
|
body: invalidGroupInfo,
|
||||||
json: true
|
json: true
|
||||||
|
|||||||
@ -9,7 +9,7 @@ The permissive nature of JavaScript along with its variety of code-flow options
|
|||||||
```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();
|
||||||
@ -20,7 +20,7 @@ const addProduct = async (productToAdd) => {
|
|||||||
try {
|
try {
|
||||||
const existingProduct = await DAL.getProduct(productToAdd.id);
|
const existingProduct = await DAL.getProduct(productToAdd.id);
|
||||||
if (existingProduct !== null) {
|
if (existingProduct !== null) {
|
||||||
throw new Error("Product already exists!");
|
throw new Error('Product already exists!');
|
||||||
}
|
}
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
// ...
|
// ...
|
||||||
@ -33,7 +33,7 @@ const addProduct = async (productToAdd) => {
|
|||||||
```javascript
|
```javascript
|
||||||
// throwing a string lacks any stack trace information and other important data properties
|
// throwing a string lacks any stack trace information and other important data properties
|
||||||
if(!productToAdd)
|
if(!productToAdd)
|
||||||
throw ("How can I add new product when no value provided?");
|
throw ('How can I add new product when no value provided?');
|
||||||
```
|
```
|
||||||
|
|
||||||
### Code example – doing it even better
|
### Code example – doing it even better
|
||||||
@ -56,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)
|
||||||
```
|
```
|
||||||
</details>
|
</details>
|
||||||
|
|
||||||
@ -85,7 +85,7 @@ export class AppError extends Error {
|
|||||||
|
|
||||||
// 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)
|
||||||
```
|
```
|
||||||
</details>
|
</details>
|
||||||
|
|
||||||
|
|||||||
@ -27,7 +27,7 @@ router.get('/ops/heapdump', (req, res, next) => {
|
|||||||
|
|
||||||
heapdump.writeSnapshot((err, filename) => {
|
heapdump.writeSnapshot((err, filename) => {
|
||||||
console.log('heapdump file is ready to be sent to the caller', filename);
|
console.log('heapdump file is ready to be sent to the caller', filename);
|
||||||
fs.readFile(filename, "utf-8", (err, data) => {
|
fs.readFile(filename, 'utf-8', (err, data) => {
|
||||||
res.end(data);
|
res.end(data);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|||||||
@ -18,7 +18,7 @@ $ node
|
|||||||
|
|
||||||
```javascript
|
```javascript
|
||||||
// Reading the environment variable using code
|
// Reading the environment variable using code
|
||||||
if (process.env.NODE_ENV === "production")
|
if (process.env.NODE_ENV === 'production')
|
||||||
useCaching = true;
|
useCaching = true;
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|||||||
@ -13,8 +13,8 @@ The latest Express generator comes with a great practice that is worth to keep -
|
|||||||
```javascript
|
```javascript
|
||||||
const app = express();
|
const app = express();
|
||||||
app.use(bodyParser.json());
|
app.use(bodyParser.json());
|
||||||
app.use("/api/events", events.API);
|
app.use('/api/events', events.API);
|
||||||
app.use("/api/forms", forms);
|
app.use('/api/forms', forms);
|
||||||
```
|
```
|
||||||
|
|
||||||
### Code example: Server network declaration, should reside in /bin/www
|
### Code example: Server network declaration, should reside in /bin/www
|
||||||
|
|||||||
@ -11,22 +11,22 @@ As a rule of thumb, one should run his own JavaScript files only. Theories aside
|
|||||||
### Code example - Using Sandbox library to run code in isolation
|
### Code example - Using Sandbox library to run code in isolation
|
||||||
|
|
||||||
```javascript
|
```javascript
|
||||||
const Sandbox = require("sandbox");
|
const Sandbox = require('sandbox');
|
||||||
const s = new Sandbox();
|
const s = new Sandbox();
|
||||||
|
|
||||||
s.run("lol)hai", (output) => {
|
s.run('lol)hai', (output) => {
|
||||||
console.log(output);
|
console.log(output);
|
||||||
//output='Syntax error'
|
//output='Syntax error'
|
||||||
});
|
});
|
||||||
|
|
||||||
// Example 4 - Restricted code
|
// Example 4 - Restricted code
|
||||||
s.run("process.platform", (output) => {
|
s.run('process.platform', (output) => {
|
||||||
console.log(output);
|
console.log(output);
|
||||||
//output=Null
|
//output=Null
|
||||||
});
|
});
|
||||||
|
|
||||||
// Example 5 - Infinite loop
|
// Example 5 - Infinite loop
|
||||||
s.run("while (true) {}", (output) => {
|
s.run('while (true) {}', (output) => {
|
||||||
console.log(output);
|
console.log(output);
|
||||||
//output='Timeout'
|
//output='Timeout'
|
||||||
});
|
});
|
||||||
|
|||||||
@ -30,7 +30,7 @@ Validation is about being very explicit on what payload our app is willing to ac
|
|||||||
### Example - Validating an entity using JSON-Schema
|
### Example - Validating an entity using JSON-Schema
|
||||||
|
|
||||||
```javascript
|
```javascript
|
||||||
const JSONValidator = require("jsonschema").Validator;
|
const JSONValidator = require('jsonschema').Validator;
|
||||||
|
|
||||||
class Product {
|
class Product {
|
||||||
|
|
||||||
@ -52,7 +52,7 @@ class Product {
|
|||||||
```javascript
|
```javascript
|
||||||
// The validator is a generic middleware that gets the entity it should validate and takes care to return
|
// The validator is a generic middleware that gets the entity it should validate and takes care to return
|
||||||
// HTTP status 400 (Bad Request) should the body payload validation fail
|
// HTTP status 400 (Bad Request) should the body payload validation fail
|
||||||
router.post("/" , **validator(Product.validate)**, async (req, res, next) => {
|
router.post('/' , **validator(Product.validate)**, async (req, res, next) => {
|
||||||
// route handling code goes here
|
// route handling code goes here
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
@ -20,7 +20,7 @@ describe.skip('Customer classifier', () => {
|
|||||||
test('When customer spent more than 500$, should be classified as premium', () => {
|
test('When customer spent more than 500$, should be classified as premium', () => {
|
||||||
//Arrange
|
//Arrange
|
||||||
const customerToClassify = {spent:505, joined: new Date(), id:1}
|
const customerToClassify = {spent:505, joined: new Date(), id:1}
|
||||||
const DBStub = sinon.stub(dataAccess, "getCustomer")
|
const DBStub = sinon.stub(dataAccess, 'getCustomer')
|
||||||
.reply({id:1, classification: 'regular'});
|
.reply({id:1, classification: 'regular'});
|
||||||
|
|
||||||
//Act
|
//Act
|
||||||
@ -38,7 +38,7 @@ describe.skip('Customer classifier', () => {
|
|||||||
```javascript
|
```javascript
|
||||||
test('Should be classified as premium', () => {
|
test('Should be classified as premium', () => {
|
||||||
const customerToClassify = {spent:505, joined: new Date(), id:1}
|
const customerToClassify = {spent:505, joined: new Date(), id:1}
|
||||||
const DBStub = sinon.stub(dataAccess, "getCustomer")
|
const DBStub = sinon.stub(dataAccess, 'getCustomer')
|
||||||
.reply({id:1, classification: 'regular'});
|
.reply({id:1, classification: 'regular'});
|
||||||
const receivedClassification = customerClassifier.classifyCustomer(customerToClassify);
|
const receivedClassification = customerClassifier.classifyCustomer(customerToClassify);
|
||||||
expect(receivedClassification).toMatch('premium');
|
expect(receivedClassification).toMatch('premium');
|
||||||
|
|||||||
@ -10,12 +10,12 @@
|
|||||||
|
|
||||||
### Code example: each test acts on its own set of data
|
### Code example: each test acts on its own set of data
|
||||||
```javascript
|
```javascript
|
||||||
it("When updating site name, get successful confirmation", async () => {
|
it('When updating site name, get successful confirmation', async () => {
|
||||||
//test is adding a fresh new records and acting on the records only
|
//test is adding a fresh new records and acting on the records only
|
||||||
const siteUnderTest = await SiteService.addSite({
|
const siteUnderTest = await SiteService.addSite({
|
||||||
name: "siteForUpdateTest"
|
name: 'siteForUpdateTest'
|
||||||
});
|
});
|
||||||
const updateNameResult = await SiteService.changeName(siteUnderTest, "newName");
|
const updateNameResult = await SiteService.changeName(siteUnderTest, 'newName');
|
||||||
expect(updateNameResult).to.be(true);
|
expect(updateNameResult).to.be(true);
|
||||||
});
|
});
|
||||||
```
|
```
|
||||||
@ -28,15 +28,15 @@ before(() => {
|
|||||||
//adding sites and admins data to our DB. Where is the data? outside. At some external json or migration framework
|
//adding sites and admins data to our DB. Where is the data? outside. At some external json or migration framework
|
||||||
await DB.AddSeedDataFromJson('seed.json');
|
await DB.AddSeedDataFromJson('seed.json');
|
||||||
});
|
});
|
||||||
it("When updating site name, get successful confirmation", async () => {
|
it('When updating site name, get successful confirmation', async () => {
|
||||||
//I know that site name "portal" exists - I saw it in the seed files
|
//I know that site name 'portal' exists - I saw it in the seed files
|
||||||
const siteToUpdate = await SiteService.getSiteByName("Portal");
|
const siteToUpdate = await SiteService.getSiteByName('Portal');
|
||||||
const updateNameResult = await SiteService.changeName(siteToUpdate, "newName");
|
const updateNameResult = await SiteService.changeName(siteToUpdate, 'newName');
|
||||||
expect(updateNameResult).to.be(true);
|
expect(updateNameResult).to.be(true);
|
||||||
});
|
});
|
||||||
it("When querying by site name, get the right site", async () => {
|
it('When querying by site name, get the right site', async () => {
|
||||||
//I know that site name "portal" exists - I saw it in the seed files
|
//I know that site name 'portal' exists - I saw it in the seed files
|
||||||
const siteToCheck = await SiteService.getSiteByName("Portal");
|
const siteToCheck = await SiteService.getSiteByName('Portal');
|
||||||
expect(siteToCheck.name).to.be.equal("Portal"); //Failure! The previous test change the name :[
|
expect(siteToCheck.name).to.be.equal('Portal'); //Failure! The previous test change the name :[
|
||||||
});
|
});
|
||||||
```
|
```
|
||||||
Reference in New Issue
Block a user