-
-
Notifications
You must be signed in to change notification settings - Fork 21.7k
Add comprehensive middleware execution order and error handling examples #6924
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Open
ViKing-Coder-jpg
wants to merge
1
commit into
expressjs:master
Choose a base branch
from
ViKing-Coder-jpg:nodeexpress
base: master
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
+103
−0
Open
Changes from all commits
Commits
File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,102 @@ | ||
| 'use strict' | ||
|
|
||
| /** | ||
| * Module dependencies. | ||
| */ | ||
|
|
||
| var express = require('../../'); // Import from the root of the repo | ||
| var app = express(); | ||
|
|
||
| // 1. Global Logging Middleware | ||
| // This runs for EVERY request | ||
| app.use(function logger(req, res, next) { | ||
| console.log('\n--- New Request ---'); | ||
| console.log(`[${new Date().toISOString()}] ${req.method} ${req.url}`); | ||
| console.log('1. Global Logger: Start'); | ||
|
|
||
| // Hook into response finish to log completion | ||
| res.on('finish', () => { | ||
| console.log('1. Global Logger: Response Sent'); | ||
| }); | ||
|
|
||
| next(); | ||
| }); | ||
|
|
||
| // 2. Middleware that modifies the request | ||
| app.use(function addTimestamp(req, res, next) { | ||
| console.log('2. Timestamp Middleware: Adding req.requestTime'); | ||
| req.requestTime = Date.now(); | ||
| next(); | ||
| }); | ||
|
|
||
| // 3. Route-specific middleware example | ||
| function validateId(req, res, next) { | ||
| console.log(' -> ValidateID Middleware: Checking ID...'); | ||
| if (req.params.id === '0') { | ||
| console.log(' -> ValidateID Middleware: ID is 0, throwing error'); | ||
| return next(new Error('ID cannot be 0')); | ||
| } | ||
| console.log(' -> ValidateID Middleware: ID is valid'); | ||
| next(); | ||
| } | ||
|
|
||
| // Route with multiple middleware | ||
| app.get('/user/:id', | ||
| validateId, | ||
| function userHandler(req, res, next) { | ||
| console.log('3. Route Handler: Executing'); | ||
| res.send(`User ID: ${req.params.id}, Requested at: ${req.requestTime}`); | ||
| console.log('3. Route Handler: Finished (response sent)'); | ||
| // Note: We don't call next() here because we sent a response. | ||
| } | ||
| ); | ||
|
|
||
| // 4. Async Middleware (Express 5 feature) | ||
| // Express 5 automatically catches errors in async functions | ||
| app.get('/async-error', async function asyncThrower(req, res, next) { | ||
| console.log('4. Async Handler: Start'); | ||
| // Simulating an async operation that fails | ||
| await new Promise(resolve => setTimeout(resolve, 100)); | ||
| console.log('4. Async Handler: Throwing error'); | ||
| throw new Error('Something went wrong in async land!'); | ||
| }); | ||
|
|
||
| // 5. Router-level middleware | ||
| var apiRouter = express.Router(); | ||
|
|
||
| apiRouter.use(function apiLogger(req, res, next) { | ||
| console.log(' [API Router] Logger: Start'); | ||
| next(); | ||
| }); | ||
|
|
||
| apiRouter.get('/data', function(req, res) { | ||
| console.log(' [API Router] Handler'); | ||
| res.json({ message: 'Hello from API' }); | ||
| }); | ||
|
|
||
| app.use('/api', apiRouter); | ||
|
|
||
| // 6. 404 Handler (Matched if no other route matches) | ||
| app.use(function notFound(req, res, next) { | ||
| console.log('5. 404 Handler: No route matched'); | ||
| res.status(404).send('Sorry, cant find that!'); | ||
| }); | ||
|
|
||
| // 7. Error Handling Middleware | ||
| // MUST have 4 arguments: (err, req, res, next) | ||
| app.use(function errorHandler(err, req, res, next) { | ||
| console.error('6. Error Handler: Caught error:', err.message); | ||
| res.status(500).send({ error: err.message }); | ||
| }); | ||
|
|
||
| /* istanbul ignore next */ | ||
| if (!module.parent) { | ||
| app.listen(3000); | ||
| console.log('Express started on port 3000'); | ||
| console.log('Try these URLs:'); | ||
| console.log(' GET http://localhost:3000/user/123'); | ||
| console.log(' GET http://localhost:3000/user/0 (Triggers error)'); | ||
| console.log(' GET http://localhost:3000/async-error (Triggers async error)'); | ||
| console.log(' GET http://localhost:3000/api/data (Router middleware)'); | ||
| console.log(' GET http://localhost:3000/unknown (404)'); | ||
| } | ||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -43,6 +43,7 @@ | |
| "encodeurl": "^2.0.0", | ||
| "escape-html": "^1.0.3", | ||
| "etag": "^1.8.1", | ||
| "express": "^5.1.0", | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Why should express have itself as a dependency? |
||
| "finalhandler": "^2.1.0", | ||
| "fresh": "^2.0.0", | ||
| "http-errors": "^2.0.0", | ||
|
|
||
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If you are not using
next()it can be omitted from the function signature. The only case when Express cares about the number of arguments in function signature is error handlers (must have exactly 4).