-
Notifications
You must be signed in to change notification settings - Fork 2
Codex-generated pull request #4
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
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -15,7 +15,9 @@ src/ | |
| index.ts | ||
| schema.ts | ||
| routes/ | ||
| index.ts | ||
| health.ts | ||
| users.ts | ||
| middleware/ | ||
| validation.ts | ||
| lib/ | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,36 +1 @@ | ||
| import { Hono } from 'hono'; | ||
| import { HTTPException } from 'hono/http-exception'; | ||
| import { env } from './lib/env'; | ||
| import { healthRoute } from './routes/health'; | ||
| import { usersRoute } from './routes/users'; | ||
|
|
||
| const app = new Hono(); | ||
|
|
||
| app.route('/health', healthRoute); | ||
| app.route('/users', usersRoute); | ||
|
|
||
| app.get('/', (c) => { | ||
| return c.json({ | ||
| name: 'BetterBase', | ||
| message: 'Bun + Hono + Drizzle starter', | ||
| }); | ||
| }); | ||
|
|
||
| app.onError((error, c) => { | ||
| if (error instanceof HTTPException) { | ||
| return c.json( | ||
| { | ||
| error: error.message, | ||
| details: (error as { cause?: unknown }).cause ?? null, | ||
| }, | ||
| error.status, | ||
| ); | ||
| } | ||
|
|
||
| return c.json({ error: 'Internal Server Error' }, 500); | ||
| }); | ||
|
|
||
| export default { | ||
| port: env.PORT, | ||
| fetch: app.fetch, | ||
| }; | ||
| import './routes/index'; |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,12 +1,11 @@ | ||
| import { Hono } from 'hono'; | ||
|
|
||
| const healthRoute = new Hono(); | ||
| export const healthRoute = new Hono(); | ||
|
|
||
| healthRoute.get('/', (c) => { | ||
| return c.json({ | ||
| status: 'ok', | ||
| service: 'betterbase-template', | ||
| status: 'healthy', | ||
| database: 'connected', | ||
| timestamp: new Date().toISOString(), | ||
| }); | ||
| }); | ||
|
|
||
| export { healthRoute }; | ||
| Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| @@ -0,0 +1,62 @@ | ||||||||||||||||||||||||||||||||||||||||||||||
| import { Hono } from 'hono'; | ||||||||||||||||||||||||||||||||||||||||||||||
| import { cors } from 'hono/cors'; | ||||||||||||||||||||||||||||||||||||||||||||||
| import { logger } from 'hono/logger'; | ||||||||||||||||||||||||||||||||||||||||||||||
| import { HTTPException } from 'hono/http-exception'; | ||||||||||||||||||||||||||||||||||||||||||||||
| import { db } from '../db'; | ||||||||||||||||||||||||||||||||||||||||||||||
| import { users } from '../db/schema'; | ||||||||||||||||||||||||||||||||||||||||||||||
| import { healthRoute } from './health'; | ||||||||||||||||||||||||||||||||||||||||||||||
| import { usersRoute } from './users'; | ||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||
| const app = new Hono(); | ||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||
| app.use('*', cors()); | ||||||||||||||||||||||||||||||||||||||||||||||
| app.use('*', logger()); | ||||||||||||||||||||||||||||||||||||||||||||||
| app.use('*', async (c, next) => { | ||||||||||||||||||||||||||||||||||||||||||||||
| const start = performance.now(); | ||||||||||||||||||||||||||||||||||||||||||||||
| await next(); | ||||||||||||||||||||||||||||||||||||||||||||||
| const duration = (performance.now() - start).toFixed(2); | ||||||||||||||||||||||||||||||||||||||||||||||
| console.log(`⏱ ${c.req.method} ${c.req.path} - ${duration}ms`); | ||||||||||||||||||||||||||||||||||||||||||||||
| }); | ||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||
| app.onError((err, c) => { | ||||||||||||||||||||||||||||||||||||||||||||||
| console.error('Error:', err); | ||||||||||||||||||||||||||||||||||||||||||||||
| return c.json( | ||||||||||||||||||||||||||||||||||||||||||||||
| { | ||||||||||||||||||||||||||||||||||||||||||||||
| error: err.message, | ||||||||||||||||||||||||||||||||||||||||||||||
| stack: process.env.NODE_ENV === 'development' ? err.stack : undefined, | ||||||||||||||||||||||||||||||||||||||||||||||
| details: err instanceof HTTPException ? (err as { cause?: unknown }).cause ?? null : null, | ||||||||||||||||||||||||||||||||||||||||||||||
| }, | ||||||||||||||||||||||||||||||||||||||||||||||
| err instanceof HTTPException ? err.status : 500, | ||||||||||||||||||||||||||||||||||||||||||||||
| ); | ||||||||||||||||||||||||||||||||||||||||||||||
| }); | ||||||||||||||||||||||||||||||||||||||||||||||
|
Comment on lines
+21
to
+31
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. Error message is exposed in all environments; only stack trace is gated.
Suggested fix return c.json(
{
- error: err.message,
+ error: process.env.NODE_ENV === 'development' ? err.message : 'Internal Server Error',
stack: process.env.NODE_ENV === 'development' ? err.stack : undefined,
details: err instanceof HTTPException ? (err as { cause?: unknown }).cause ?? null : null,
},For 📝 Committable suggestion
Suggested change
🤖 Prompt for AI Agents |
||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||
| app.route('/health', healthRoute); | ||||||||||||||||||||||||||||||||||||||||||||||
| app.route('/users', usersRoute); | ||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||
| app.get('/api/users', async (c) => { | ||||||||||||||||||||||||||||||||||||||||||||||
| const allUsers = await db.select().from(users); | ||||||||||||||||||||||||||||||||||||||||||||||
| return c.json({ users: allUsers }); | ||||||||||||||||||||||||||||||||||||||||||||||
| }); | ||||||||||||||||||||||||||||||||||||||||||||||
|
Comment on lines
+33
to
+39
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. Duplicate and inconsistent user routes.
Move the GET handler into Suggested fix (in routes/index.ts) app.route('/health', healthRoute);
-app.route('/users', usersRoute);
-
-app.get('/api/users', async (c) => {
- const allUsers = await db.select().from(users);
- return c.json({ users: allUsers });
-});
+app.route('/api/users', usersRoute);Then add the GET handler inside 🤖 Prompt for AI Agents |
||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||
| const server = Bun.serve({ | ||||||||||||||||||||||||||||||||||||||||||||||
| fetch: app.fetch, | ||||||||||||||||||||||||||||||||||||||||||||||
| port: Number(process.env.PORT ?? 3000), | ||||||||||||||||||||||||||||||||||||||||||||||
| development: process.env.NODE_ENV === 'development', | ||||||||||||||||||||||||||||||||||||||||||||||
| }); | ||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||
| console.log('\x1b[32m🚀 BetterBase dev server started\x1b[0m'); | ||||||||||||||||||||||||||||||||||||||||||||||
| console.log(`\x1b[36m→ URL:\x1b[0m http://localhost:${server.port}`); | ||||||||||||||||||||||||||||||||||||||||||||||
| console.log('\x1b[35m→ Routes:\x1b[0m'); | ||||||||||||||||||||||||||||||||||||||||||||||
| console.log(' GET /health'); | ||||||||||||||||||||||||||||||||||||||||||||||
| console.log(' GET /api/users'); | ||||||||||||||||||||||||||||||||||||||||||||||
| console.log(' POST /users'); | ||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||
| process.on('SIGTERM', () => { | ||||||||||||||||||||||||||||||||||||||||||||||
| console.log('SIGTERM received, closing server...'); | ||||||||||||||||||||||||||||||||||||||||||||||
| server.stop(); | ||||||||||||||||||||||||||||||||||||||||||||||
| }); | ||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||
| process.on('SIGINT', () => { | ||||||||||||||||||||||||||||||||||||||||||||||
| console.log('SIGINT received, closing server...'); | ||||||||||||||||||||||||||||||||||||||||||||||
| server.stop(); | ||||||||||||||||||||||||||||||||||||||||||||||
| }); | ||||||||||||||||||||||||||||||||||||||||||||||
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.
Hardcoded
database: 'connected'is misleading.The health endpoint always reports
"database": "connected"regardless of actual database state. This can mask outages. Either perform a real connectivity check (e.g., a trivialSELECT 1via the Drizzle client) or remove the field until a real check is implemented.🤖 Prompt for AI Agents