Skip to content

Commit dd14919

Browse files
committed
error handler middleware
1 parent 980325d commit dd14919

9 files changed

Lines changed: 208 additions & 250 deletions

File tree

package-lock.json

Lines changed: 9 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
"dotenv": "^16.4.5",
1616
"env-var": "^7.4.1",
1717
"express": "^4.19.2",
18+
"express-async-errors": "^3.1.1",
1819
"joi": "^17.12.2",
1920
"knex": "^3.1.0",
2021
"pg": "^8.11.3",

src/controllers/currencyController.ts

Lines changed: 35 additions & 68 deletions
Original file line numberDiff line numberDiff line change
@@ -1,36 +1,25 @@
11
import { Request, Response } from "express";
22
import { currencyService } from "../services/currencyService";
33
import { Conversion, Currency } from "../types/currency";
4+
import { BadRequestError } from "../utils/apiError";
45

56
const listCurrencies = async (_: Request, res: Response) => {
6-
try {
7-
const currencies = await currencyService.getCurrencies();
8-
9-
return res.status(200).json(currencies);
10-
} catch (error: any) {
11-
return res.status(500).json({ message: error.message });
12-
}
7+
const currencies = await currencyService.getCurrencies();
8+
return res.status(200).json(currencies);
139
};
1410

1511
const getCurrency = async (req: Request, res: Response) => {
1612
const code = (req.params.code as string).toUpperCase();
1713

18-
try {
19-
const supportedCurrencies =
20-
await currencyService.getSupportedCurrencies();
14+
const supportedCurrencies = await currencyService.getSupportedCurrencies();
2115

22-
if (!supportedCurrencies.includes(code)) {
23-
return res
24-
.status(400)
25-
.json({ message: "The currency is not supported" });
26-
}
16+
if (!supportedCurrencies.includes(code)) {
17+
throw new BadRequestError("The currency is not supported");
18+
}
2719

28-
const currency = await currencyService.getCurrency(code);
20+
const currency = await currencyService.getCurrency(code);
2921

30-
return res.status(200).json(currency);
31-
} catch (error: any) {
32-
return res.status(500).json({ message: error.message });
33-
}
22+
return res.status(200).json(currency);
3423
};
3524

3625
const convertCurrency = async (req: Request, res: Response) => {
@@ -43,36 +32,29 @@ const convertCurrency = async (req: Request, res: Response) => {
4332
const uppercaseFrom = from.toUpperCase();
4433
const uppercaseTo = to.toUpperCase();
4534

46-
try {
47-
const supportedCurrencies =
48-
await currencyService.getSupportedCurrencies();
49-
50-
if (!supportedCurrencies.includes(uppercaseFrom)) {
51-
return res
52-
.status(400)
53-
.json({ message: "The currency from is not supported" });
54-
}
55-
56-
if (!supportedCurrencies.includes(uppercaseTo)) {
57-
return res
58-
.status(400)
59-
.json({ message: "The currency to is not supported" });
60-
}
61-
62-
const data: Conversion = {
63-
from: uppercaseFrom,
64-
to: uppercaseTo,
65-
amount,
66-
};
67-
68-
const conversion: Conversion = await currencyService.getConversion(
69-
data
35+
const supportedCurrencies = await currencyService.getSupportedCurrencies();
36+
37+
if (!supportedCurrencies.includes(uppercaseFrom)) {
38+
throw new BadRequestError(
39+
`The currency ${uppercaseFrom} is not supported`
7040
);
41+
}
7142

72-
return res.status(200).json(conversion);
73-
} catch (error: any) {
74-
return res.status(500).json({ message: error.message });
43+
if (!supportedCurrencies.includes(uppercaseTo)) {
44+
throw new BadRequestError(
45+
`The currency ${uppercaseTo} is not supported`
46+
);
7547
}
48+
49+
const data: Conversion = {
50+
from: uppercaseFrom,
51+
to: uppercaseTo,
52+
amount,
53+
};
54+
55+
const conversion: Conversion = await currencyService.getConversion(data);
56+
57+
return res.status(200).json(conversion);
7658
};
7759

7860
const createCurrency = async (req: Request, res: Response) => {
@@ -84,13 +66,8 @@ const createCurrency = async (req: Request, res: Response) => {
8466
value,
8567
};
8668

87-
try {
88-
await currencyService.createCurrency(currency);
89-
90-
return res.status(201).json(currency);
91-
} catch (error: any) {
92-
return res.status(500).json({ message: error.message });
93-
}
69+
await currencyService.createCurrency(currency);
70+
return res.status(201).json(currency);
9471
};
9572

9673
const updateCurrency = async (req: Request, res: Response) => {
@@ -103,25 +80,15 @@ const updateCurrency = async (req: Request, res: Response) => {
10380
value,
10481
};
10582

106-
try {
107-
await currencyService.updateCurrency(codeParams, currency);
108-
109-
return res.status(204).send();
110-
} catch (error: any) {
111-
return res.status(500).json({ message: error.message });
112-
}
83+
await currencyService.updateCurrency(codeParams, currency);
84+
return res.status(204).send();
11385
};
11486

11587
const deleteCurrency = async (req: Request, res: Response) => {
11688
const code = (req.params.code as string).toUpperCase();
11789

118-
try {
119-
await currencyService.deleteCurrency(code);
120-
121-
return res.status(204).send();
122-
} catch (error: any) {
123-
return res.status(500).json({ message: error.message });
124-
}
90+
await currencyService.deleteCurrency(code);
91+
return res.status(204).send();
12592
};
12693

12794
export const currencyController = {

src/index.ts

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,18 @@
11
import "dotenv/config";
2+
import 'express-async-errors'
23
import env from "./config/envConfig";
34
import express from "express";
45
import redis from "./database/redis";
56

67
import currencyRoutes from "./routes/currencyRoute";
8+
import errorMiddleware from "./middlewares/error";
79

810
redis.connect();
9-
1011
const app = express();
1112

1213
app.use(express.json());
1314

1415
app.use(currencyRoutes);
16+
app.use(errorMiddleware)
1517

1618
app.listen(env.PORT, () => console.log(`Server running on port ${env.PORT}`));

src/middlewares/error.ts

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
import { Request, Response, NextFunction } from "express";
2+
import { ApiError } from "../utils/apiError";
3+
4+
export default function errorMiddleware(
5+
error: Error & Partial<ApiError>,
6+
req: Request,
7+
res: Response,
8+
next: NextFunction
9+
) {
10+
const statusCode = error.statusCode ?? 500;
11+
const message = statusCode !== 500 ? error.message : "Internal server error";
12+
res.status(statusCode).json({ message });
13+
}
Lines changed: 12 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import { Request, Response, NextFunction } from "express";
22
import { ObjectSchema } from "joi";
3+
import { BadRequestError } from "../utils/apiError";
34

45
const requestValidation =
56
(schema: ObjectSchema) =>
@@ -8,26 +9,20 @@ const requestValidation =
89
const params = Object.keys(req.params).length;
910
const query = Object.keys(req.query).length;
1011
if (req.method !== "GET" && !body && !params && !query) {
11-
return res
12-
.status(400)
13-
.json({ message: "Please fill out all the fields" });
12+
throw new BadRequestError("Please fill out all the fields");
1413
}
1514

16-
try {
17-
if (body) {
18-
await schema.validateAsync({ body: req.body });
19-
}
20-
if (params) {
21-
await schema.validateAsync({ params: req.params });
22-
}
23-
if (query) {
24-
await schema.validateAsync({ query: req.query });
25-
}
26-
27-
return next();
28-
} catch (error: any) {
29-
return res.status(400).json({ message: error.message });
15+
if (body) {
16+
await schema.validateAsync({ body: req.body });
17+
}
18+
if (params) {
19+
await schema.validateAsync({ params: req.params });
3020
}
21+
if (query) {
22+
await schema.validateAsync({ query: req.query });
23+
}
24+
25+
return next();
3126
};
3227

3328
export default requestValidation;

src/routes/currencyRoute.ts

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@ import { Router } from "express";
22
import { currencyController } from "../controllers/currencyController";
33
import joi from "../middlewares/requestValidation";
44
import { schema } from "../models/joiCurrency";
5-
import redis from "../database/redis";
65

76
const route = Router();
87

0 commit comments

Comments
 (0)