Skip to content

Commit 2223be8

Browse files
author
Pratik Das
committed
error handling code
1 parent 385c8f7 commit 2223be8

8 files changed

Lines changed: 335 additions & 0 deletions

File tree

nodejs/errorhandling/README.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
# Examples for [Error Handling in Express](guide-to-error-handling-in-express)
2+
3+
This repository contains the source code of the article's examples.

nodejs/errorhandling/js/index.js

Lines changed: 94 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,94 @@
1+
const express = require('express')
2+
const axios = require("axios")
3+
// const morgan = require('morgan')
4+
5+
const app = express()
6+
7+
8+
const requestLogger = (request, response, next) => {
9+
console.log(`${request.method} url:: ${request.url}`);
10+
next()
11+
}
12+
13+
app.use(express.static('images'))
14+
app.use(express.static('htmls'))
15+
16+
app.use('/products', express.json({ limit: 100 }))
17+
18+
// Error handling Middleware functions
19+
const errorLogger = (error, request, response, next) => {
20+
console.log( `error ${error.message}`)
21+
next(error) // calling next middleware
22+
}
23+
24+
const errorResponder = (error, request, response, next) => {
25+
response.header("Content-Type", 'application/json')
26+
27+
const status = error.status || 400
28+
response.status(status).send(error.message)
29+
}
30+
const invalidPathHandler = (request, response, next) => {
31+
response.status(400)
32+
response.send('invalid path')
33+
}
34+
35+
36+
// handle post request for path /products
37+
app.post('/products', (request, response) => {
38+
const products = []
39+
40+
const name = request.body.name
41+
42+
const brand = request.body.brand
43+
44+
const category = request.body.category
45+
46+
if(name == null){
47+
res.status(500).json({ message: "Mandatory field name is missing. " })
48+
}else{
49+
console.log(name + " " + brand)
50+
51+
products.push({name: request.body.name, brand: request.body.brand, price: request.body.price})
52+
53+
const productCreationResponse = {productID: "12345", result: "success"}
54+
response.json(productCreationResponse)
55+
}
56+
})
57+
58+
app.get('/products', async (request, response, next)=>{
59+
try{
60+
const apiResponse = await axios.get("http://localhost:3001/products")
61+
62+
const jsonResponse = apiResponse.data
63+
console.log("response "+jsonResponse)
64+
65+
response.send(jsonResponse)
66+
}catch(error){
67+
next(error)
68+
}
69+
70+
})
71+
72+
app.get('/product', (request, response, next)=>{
73+
74+
axios.get("http://localhost:3001/product")
75+
.then(response=>response.json)
76+
.then(jsonresponse=>response.send(jsonresponse))
77+
.catch(next)
78+
})
79+
80+
app.get('/productswitherror', (request, response) => {
81+
let error = new Error(`processing error in request at ${request.url}`)
82+
error.statusCode = 400
83+
throw error
84+
})
85+
86+
app.use(errorLogger)
87+
app.use(errorResponder)
88+
app.use(invalidPathHandler)
89+
90+
const port = 3000
91+
92+
app.listen(3000,
93+
() => console.log(`Server listening on port ${port}.`));
94+

nodejs/errorhandling/js/lambda.js

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
console.log('Loading function');
2+
3+
const validateRecord = (recordElement)=>{
4+
// record is considered valid if contains status field
5+
return recordElement.includes("status")
6+
}
7+
8+
exports.handler = async (event, context) => {
9+
/* Process the list of records and transform them */
10+
const output = event.records.map((record)=>{
11+
const decodedData = Buffer.from(record.data, "base64").toString("utf-8")
12+
let isValidRecord = validateRecord(decodedData)
13+
14+
if(isValidRecord){
15+
let parsedRecord = JSON.parse(decodedData)
16+
// read fields from parsed JSON for some more processing
17+
const outputRecord = `status::${parsedRecord.status}`
18+
return {
19+
recordId: record.recordId,
20+
result: 'Ok',
21+
// payload is encoded back to base64 before returning the result
22+
data: Buffer.from(outputRecord, "utf-8").toString("base64")
23+
}
24+
25+
}else{
26+
return {
27+
recordId: record.recordId,
28+
result: 'dropped',
29+
data: record.data // payload is kept intact,
30+
}
31+
}
32+
})
33+
};

nodejs/errorhandling/js/server.js

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
const express = require('express')
2+
// const morgan = require('morgan')
3+
4+
const app = express()
5+
6+
const port = 3001
7+
8+
const products = [
9+
{name:"Television", price: 24.56, currency: "USG", brand: "samsung"},
10+
{name:"Washing Machine", price: 67.56, currency: "EUR", brand: "LG"}
11+
]
12+
13+
app.get('/products', (request, response)=>{
14+
15+
response.json(products)
16+
})
17+
18+
app.listen(port,
19+
() => console.log(`Server listening on port ${port}.`))
20+

nodejs/errorhandling/package.json

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
{
2+
"name": "storefront",
3+
"version": "1.0.0",
4+
"description": "",
5+
"main": "js/index.js",
6+
"scripts": {
7+
"test": "echo \"Error: no test specified\" && exit 1"
8+
},
9+
"keywords": [],
10+
"author": "",
11+
"license": "ISC",
12+
"dependencies": {
13+
"axios": "^0.26.1",
14+
"express": "^4.17.3",
15+
"node-fetch": "^3.2.2"
16+
},
17+
"devDependencies": {
18+
"@types/express": "^4.17.13",
19+
"@types/node": "^17.0.23",
20+
"ts-node": "^10.7.0",
21+
"typescript": "^4.6.3"
22+
}
23+
}

nodejs/errorhandling/ts/app.ts

Lines changed: 126 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,126 @@
1+
import express, { Request, Response, NextFunction } from 'express'
2+
import axios from 'axios'
3+
4+
const app = express()
5+
const port:number = 3000
6+
7+
8+
interface Product {
9+
10+
name: string
11+
price: number
12+
brand: string
13+
category?: string
14+
}
15+
16+
interface ProductCreationResponse {
17+
productID: string
18+
result: string
19+
}
20+
21+
22+
class AppError extends Error{
23+
statusCode: number;
24+
25+
constructor(statusCode: number, message: string) {
26+
super(message);
27+
28+
Object.setPrototypeOf(this, new.target.prototype);
29+
this.name = Error.name;
30+
this.statusCode = statusCode;
31+
Error.captureStackTrace(this);
32+
}
33+
}
34+
35+
const requestLogger = (request: Request, response: Response, next: NextFunction) => {
36+
console.log(`${request.method} url:: ${request.url}`);
37+
next()
38+
}
39+
40+
app.use(express.static('images'))
41+
app.use(express.static('htmls'))
42+
app.use(requestLogger)
43+
44+
app.use('/products', express.json({ limit: 100 }))
45+
46+
// Error handling Middleware functions
47+
const errorLogger = (error: Error, request: Request, response: Response, next: NextFunction) => {
48+
console.log( `error ${error.message}`)
49+
next(error) // calling next middleware
50+
}
51+
52+
const errorResponder = (error: AppError, request: Request, response: Response, next: NextFunction) => {
53+
response.header("Content-Type", 'application/json')
54+
55+
const status = error.statusCode || 400
56+
response.status(status).send(error.message)
57+
}
58+
59+
const invalidPathHandler = (request: Request, response: Response, next: NextFunction) => {
60+
response.status(400)
61+
response.send('invalid path')
62+
}
63+
64+
65+
// handle post request for path /products
66+
app.post('/products', (request: Request, response: Response) => {
67+
const products = []
68+
69+
const name = request.body.name
70+
71+
const brand = request.body.brand
72+
73+
const category = request.body.category
74+
75+
if(name == null){
76+
response.status(500).json({ message: "Mandatory field name is missing. " })
77+
}else{
78+
console.log(name + " " + brand)
79+
80+
products.push({name: request.body.name, brand: request.body.brand, price: request.body.price})
81+
82+
const productCreationResponse = {productID: "12345", result: "success"}
83+
response.json(productCreationResponse)
84+
}
85+
})
86+
87+
app.get('/products', async (request: Request, response: Response, next: NextFunction)=>{
88+
try{
89+
const apiResponse = await axios.get("http://localhost:3001/products")
90+
91+
const jsonResponse = apiResponse.data
92+
console.log("response "+jsonResponse)
93+
94+
response.send(jsonResponse)
95+
}catch(error){
96+
next(error)
97+
}
98+
99+
})
100+
101+
app.get('/product', (request: Request, response: Response, next: NextFunction)=>{
102+
103+
axios.get("http://localhost:3001/product")
104+
.then(jsonresponse=>response.send(jsonresponse))
105+
.catch(next)
106+
})
107+
108+
app.get('/productswitherror', (request, response) => {
109+
let error:AppError = new AppError(400, `processing error in request at ${request.url}`)
110+
error.statusCode = 400
111+
throw error
112+
})
113+
114+
app.get('/productswitherror', (request: Request, response: Response) => {
115+
let error: AppError = new AppError(400, `processing error in request at ${request.url}`)
116+
117+
throw error
118+
})
119+
120+
app.use(errorLogger)
121+
app.use(errorResponder)
122+
app.use(invalidPathHandler)
123+
124+
app.listen(port, () => {
125+
console.log(`Server listening at port ${port}.`)
126+
})

nodejs/errorhandling/ts/server.ts

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
import express, { Request, Response, NextFunction } from 'express'
2+
3+
const app = express()
4+
5+
const port:number = 3001
6+
7+
interface Product {
8+
9+
name: string
10+
price: number
11+
currency: string
12+
brand: string
13+
category?: string
14+
}
15+
16+
const products: Product[] = [
17+
{name:"Television", price: 24.56, currency: "USG", brand: "samsung"},
18+
{name:"Washing Machine", price: 67.56, currency: "EUR", brand: "LG"}
19+
]
20+
21+
app.get('/products', (request: Request, response: Response)=>{
22+
23+
response.json(products)
24+
})
25+
26+
app.listen(port,
27+
() => console.log(`Server listening on port ${port}.`))
28+

nodejs/errorhandling/tsconfig.json

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
{
2+
"compilerOptions": {
3+
"module": "commonjs",
4+
"target": "es6",
5+
"rootDir": "./ts",
6+
"esModuleInterop": true
7+
}
8+
}

0 commit comments

Comments
 (0)