Skip to content

Commit 8e766d2

Browse files
committed
fix: Simplify shutdown error handling and fix 404 error reporting
- Remove redundant withTimeout wrapper from shutdown disconnect calls since ConnectionFlowManager now handles timeouts internally - Add error re-throw in disconnectContext to ensure Promise.allSettled properly tracks rejected promises - Fix 404 catch-all route to use req.originalUrl instead of req.path for more accurate error reporting - Add Express.js skill documentation and permissions for git/pr workflows
1 parent ce65074 commit 8e766d2

13 files changed

Lines changed: 4577 additions & 10 deletions

File tree

.claude/settings.local.json

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,24 @@
1414
"WebFetch(domain:github.com)",
1515
"WebFetch(domain:www.npmjs.com)",
1616
"WebFetch(domain:raw.githubusercontent.com)",
17-
"WebFetch(domain:api.github.com)"
17+
"WebFetch(domain:api.github.com)",
18+
"Bash(gh pr view:*)",
19+
"Bash(gh pr diff:*)",
20+
"Bash(gh pr checkout:*)",
21+
"Bash(git commit:*)",
22+
"Bash(git push:*)",
23+
"Bash(gh run list:*)",
24+
"Bash(gh workflow list:*)",
25+
"Bash(grep:*)",
26+
"Bash(gh run:*)",
27+
"Bash(gh pr create:*)",
28+
"Bash(gh pr:*)",
29+
"Bash(./dist/flashforge-webui-win-x64.exe --no-printers)",
30+
"Bash(python:*)",
31+
"Bash(npx yao-pkg:*)",
32+
"Bash(gh api:*)",
33+
"Bash(ls:*)",
34+
"Bash(git remote get-url:*)"
1835
],
1936
"deny": [],
2037
"ask": []
Lines changed: 248 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,248 @@
1+
---
2+
name: express
3+
description: Express.js 5.x web framework for Node.js - complete API reference, middleware patterns, routing, error handling, and production best practices. Use when building Express applications, creating REST APIs, implementing middleware, handling routes, managing errors, configuring security, optimizing performance, or migrating from Express 4 to 5. Triggers on Express, express.js, Node.js web server, REST API, middleware, routing, req/res objects, app.use, app.get, app.post, router, error handling, body-parser, static files, template engines.
4+
---
5+
6+
# Express.js 5.x Development Skill
7+
8+
Express is a minimal and flexible Node.js web application framework providing robust features for web and mobile applications. This skill covers Express 5.x (current stable, requires Node.js 18+).
9+
10+
## Quick Reference
11+
12+
### Creating an Express Application
13+
14+
```javascript
15+
const express = require('express')
16+
const app = express()
17+
18+
// Built-in middleware
19+
app.use(express.json()) // Parse JSON bodies
20+
app.use(express.urlencoded({ extended: true })) // Parse URL-encoded bodies
21+
app.use(express.static('public')) // Serve static files
22+
23+
// Route handling
24+
app.get('/', (req, res) => {
25+
res.send('Hello World')
26+
})
27+
28+
app.listen(3000, () => {
29+
console.log('Server running on port 3000')
30+
})
31+
```
32+
33+
### Express 5.x Key Changes from v4
34+
35+
Express 5 has breaking changes - review before migrating:
36+
37+
- **Async error handling**: Rejected promises automatically call `next(err)`
38+
- **Wildcard routes**: Must be named: `/*splat` not `/*`
39+
- **Optional params**: Use braces: `/:file{.:ext}` not `/:file.:ext?`
40+
- **Removed methods**: `app.del()``app.delete()`, `res.sendfile()``res.sendFile()`
41+
- **req.body**: Returns `undefined` (not `{}`) when unparsed
42+
- **req.query**: No longer writable, uses "simple" parser by default
43+
44+
See `references/guide/migration-v5.md` for complete migration guide.
45+
46+
## Reference Documentation Structure
47+
48+
```
49+
references/
50+
├── api/
51+
│ └── api-reference.md # Complete API: express(), app, req, res, router
52+
├── guide/
53+
│ ├── routing.md # Route methods, paths, parameters, handlers
54+
│ ├── middleware.md # Writing and using middleware
55+
│ ├── error-handling.md # Error catching and custom handlers
56+
│ └── migration-v5.md # Express 4 to 5 migration guide
57+
├── advanced/
58+
│ ├── security.md # Security best practices (Helmet, TLS, cookies)
59+
│ └── performance.md # Performance optimization and deployment
60+
└── getting-started/
61+
└── quickstart.md # Installation, hello world, project setup
62+
```
63+
64+
## Core Concepts
65+
66+
### Application Object (`app`)
67+
68+
The `app` object represents the Express application:
69+
70+
```javascript
71+
const app = express()
72+
73+
// Settings
74+
app.set('view engine', 'pug')
75+
app.set('trust proxy', true)
76+
app.enable('case sensitive routing')
77+
78+
// Mounting middleware and routes
79+
app.use(middleware)
80+
app.use('/api', apiRouter)
81+
82+
// HTTP methods
83+
app.get('/path', handler)
84+
app.post('/path', handler)
85+
app.put('/path', handler)
86+
app.delete('/path', handler)
87+
app.all('/path', handler) // All methods
88+
```
89+
90+
### Request Object (`req`)
91+
92+
Key properties and methods:
93+
94+
| Property | Description |
95+
|----------|-------------|
96+
| `req.params` | Route parameters (e.g., `/users/:id``req.params.id`) |
97+
| `req.query` | Query string parameters |
98+
| `req.body` | Parsed request body (requires body-parsing middleware) |
99+
| `req.headers` | Request headers |
100+
| `req.method` | HTTP method |
101+
| `req.path` | Request path |
102+
| `req.ip` | Client IP address |
103+
| `req.cookies` | Cookies (requires cookie-parser) |
104+
105+
### Response Object (`res`)
106+
107+
Key methods:
108+
109+
| Method | Description |
110+
|--------|-------------|
111+
| `res.send(body)` | Send response (auto content-type) |
112+
| `res.json(obj)` | Send JSON response |
113+
| `res.status(code)` | Set status code (chainable) |
114+
| `res.redirect([status,] path)` | Redirect request |
115+
| `res.render(view, locals)` | Render template |
116+
| `res.sendFile(path)` | Send file |
117+
| `res.download(path)` | Prompt file download |
118+
| `res.set(header, value)` | Set response header |
119+
| `res.cookie(name, value)` | Set cookie |
120+
121+
### Router
122+
123+
Create modular route handlers:
124+
125+
```javascript
126+
const router = express.Router()
127+
128+
router.use(authMiddleware) // Router-specific middleware
129+
130+
router.get('/', listUsers)
131+
router.get('/:id', getUser)
132+
router.post('/', createUser)
133+
router.put('/:id', updateUser)
134+
router.delete('/:id', deleteUser)
135+
136+
// Mount in app
137+
app.use('/users', router)
138+
```
139+
140+
## Common Patterns
141+
142+
### Middleware Chain
143+
144+
```javascript
145+
// Logging → Auth → Route Handler → Error Handler
146+
app.use(morgan('combined'))
147+
app.use(authMiddleware)
148+
app.use('/api', apiRoutes)
149+
app.use(errorHandler) // Must be last, has 4 params: (err, req, res, next)
150+
```
151+
152+
### Error Handling (Express 5)
153+
154+
```javascript
155+
// Async errors are caught automatically in Express 5
156+
app.get('/user/:id', async (req, res) => {
157+
const user = await User.findById(req.params.id) // Errors auto-forwarded
158+
if (!user) {
159+
const err = new Error('User not found')
160+
err.status = 404
161+
throw err
162+
}
163+
res.json(user)
164+
})
165+
166+
// Error handler middleware (4 arguments required)
167+
app.use((err, req, res, next) => {
168+
console.error(err.stack)
169+
res.status(err.status || 500).json({
170+
error: process.env.NODE_ENV === 'production'
171+
? 'Internal server error'
172+
: err.message
173+
})
174+
})
175+
```
176+
177+
### RESTful API Structure
178+
179+
```javascript
180+
const express = require('express')
181+
const app = express()
182+
183+
app.use(express.json())
184+
185+
// Routes
186+
const usersRouter = require('./routes/users')
187+
const postsRouter = require('./routes/posts')
188+
189+
app.use('/api/users', usersRouter)
190+
app.use('/api/posts', postsRouter)
191+
192+
// 404 handler
193+
app.use((req, res) => {
194+
res.status(404).json({ error: 'Not found' })
195+
})
196+
197+
// Error handler
198+
app.use((err, req, res, next) => {
199+
res.status(err.status || 500).json({ error: err.message })
200+
})
201+
```
202+
203+
### Static Files with Virtual Path
204+
205+
```javascript
206+
// Serve ./public at /static
207+
app.use('/static', express.static('public', {
208+
maxAge: '1d',
209+
etag: true,
210+
index: 'index.html'
211+
}))
212+
```
213+
214+
## When to Read Reference Files
215+
216+
| Task | Reference File |
217+
|------|----------------|
218+
| Look up specific API method | `references/api/api-reference.md` |
219+
| Implement routing patterns | `references/guide/routing.md` |
220+
| Create custom middleware | `references/guide/middleware.md` |
221+
| Handle errors properly | `references/guide/error-handling.md` |
222+
| Migrate from Express 4 | `references/guide/migration-v5.md` |
223+
| Security hardening | `references/advanced/security.md` |
224+
| Performance optimization | `references/advanced/performance.md` |
225+
| Set up new project | `references/getting-started/quickstart.md` |
226+
227+
## Production Checklist
228+
229+
1. **Security**: Use Helmet, set secure cookies, validate input
230+
2. **Performance**: Enable gzip, use clustering, cache responses
231+
3. **Environment**: Set `NODE_ENV=production`
232+
4. **Error handling**: Never expose stack traces in production
233+
5. **Logging**: Use async logger (Pino), not console.log
234+
6. **Process management**: Use systemd or PM2
235+
7. **Reverse proxy**: Run behind Nginx/HAProxy for TLS and load balancing
236+
237+
## Key Dependencies
238+
239+
| Package | Purpose |
240+
|---------|---------|
241+
| `helmet` | Security headers |
242+
| `cors` | CORS handling |
243+
| `morgan` | HTTP request logging |
244+
| `compression` | Gzip compression |
245+
| `cookie-parser` | Cookie parsing |
246+
| `express-session` | Session management |
247+
| `express-validator` | Input validation |
248+
| `multer` | File uploads |

0 commit comments

Comments
 (0)