Skip to content

Commit

Permalink
feat: ✨ request timeout
Browse files Browse the repository at this point in the history
  • Loading branch information
louiscavalcante committed Jan 11, 2024
1 parent b5ea08f commit 151819a
Show file tree
Hide file tree
Showing 6 changed files with 103 additions and 6 deletions.
2 changes: 0 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,4 @@ $ npm run dev:requirements

## WYP

- Request timeout

- Unit tests
89 changes: 89 additions & 0 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 2 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@
},
"dependencies": {
"axios": "^1.6.4",
"connect-timeout": "^1.9.0",
"date-fns": "^2.29.3",
"express": "^4.18.2",
"express-openapi-validator": "^5.1.2",
Expand All @@ -41,6 +42,7 @@
"@babel/node": "^7.22.19",
"@babel/preset-env": "^7.23.6",
"@babel/preset-typescript": "^7.23.3",
"@types/connect-timeout": "^0.0.39",
"@types/express": "^4.17.21",
"@types/jest": "^29.5.11",
"@types/node": "^20.10.5",
Expand Down
10 changes: 8 additions & 2 deletions src/app.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import express, { Express, Request, Response } from 'express'
import timeout from 'connect-timeout'
import express, { Express, Request, Response, NextFunction } from 'express'
import * as OpenApiValidator from 'express-openapi-validator'
import { Server } from 'http'
import { Socket } from 'net'
Expand Down Expand Up @@ -39,8 +40,9 @@ export default class App {
})
)

this.app.use(timeout('15s'))
this.initRoutes([UsersControllerFactory.create()])

this.app.use(this.haltOnTimedout)
this.app.use(ErrorHandler.middleware())
}

Expand All @@ -50,6 +52,10 @@ export default class App {
)
}

private haltOnTimedout(req: Request, res: Response, next: NextFunction): void {
if (!req.timedout) next()
}

private healthCheck(): Express {
return this.app.get('/_health', (_req: Request, res: Response) => {
res.status(200).send('ok')
Expand Down
4 changes: 3 additions & 1 deletion src/application/controllers/users.controller.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,9 +21,11 @@ export default class UsersController implements IControllers {
private getUsers = async (req: Request, res: Response, next: NextFunction): Promise<void> => {
try {
const results = await this.service.getUsers()

// The line below tests timeouts.
// await new Promise(resolve => setTimeout(resolve, 40000))
// await new Promise(resolve => setTimeout(resolve, 5000))

if (req.timedout) return
res.status(200).send(results)
} catch (error) {
next(error)
Expand Down
2 changes: 1 addition & 1 deletion src/application/middlewares/error-handler.middleware.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import { DomainError } from '@shared/custom-errors'

export default class ErrorHandler {
public static middleware(): ErrorRequestHandler {
return (error: ICustomError, req: Request, res: Response, _next: NextFunction) => {
return (error: ICustomError, _req: Request, res: Response, _next: NextFunction) => {
error.stack = error.status === 404 || error instanceof DomainError ? '' : error.stack

const logLevel = error instanceof DomainError ? 'warn' : 'error'
Expand Down

0 comments on commit 151819a

Please sign in to comment.