Skip to content

Commit d525106

Browse files
committed
Enhance todos API with detailed debug information and error handling
- Added comprehensive debug logging for both GET and POST requests in the todos API, including step-by-step tracking of actions and results. - Improved error handling to provide detailed feedback in case of failures, including specific error messages and debug information. - Updated the response structure to include success status and debug data for better client-side troubleshooting.
1 parent 23a39f8 commit d525106

File tree

1 file changed

+117
-19
lines changed

1 file changed

+117
-19
lines changed

apps/web/src/app/api/todos/route.ts

Lines changed: 117 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1,37 +1,78 @@
11
import { db, todos } from "@/db";
2-
import { desc } from "drizzle-orm";
2+
import { count, desc } from "drizzle-orm";
33
import { NextResponse } from "next/server";
44

55
// GET /api/todos - List all todos
66
export async function GET() {
7-
try {
8-
console.log("Starting todos fetch...");
7+
const debugInfo: any = {
8+
timestamp: new Date().toISOString(),
9+
steps: [],
10+
environment: {
11+
NODE_ENV: process.env.NODE_ENV,
12+
DATABASE_URL_exists: !!process.env.DATABASE_URL,
13+
DATABASE_URL_length: process.env.DATABASE_URL?.length || 0,
14+
},
15+
};
916

10-
// Test database connection first
11-
console.log("Testing basic database connection...");
12-
await db.execute("SELECT 1");
13-
console.log("Database connection OK");
17+
try {
18+
// Step 1: Test basic table access with count
19+
debugInfo.steps.push({
20+
step: 1,
21+
action: "Testing table access with count query",
22+
});
23+
const countResult = await db.select({ count: count() }).from(todos);
24+
const todoCount = countResult[0]?.count || 0;
25+
debugInfo.steps.push({
26+
step: 1,
27+
result: "success",
28+
todoCount,
29+
message: `Table accessible, found ${todoCount} todos`,
30+
});
1431

15-
// Try the actual query
16-
console.log("Executing todos query...");
32+
// Step 2: Try to fetch actual todos
33+
debugInfo.steps.push({
34+
step: 2,
35+
action: "Fetching all todos with ordering",
36+
});
1737
const allTodos = await db
1838
.select()
1939
.from(todos)
2040
.orderBy(desc(todos.createdAt));
2141

22-
console.log(`Found ${allTodos.length} todos`);
23-
return NextResponse.json(allTodos);
42+
debugInfo.steps.push({
43+
step: 2,
44+
result: "success",
45+
todosReturned: allTodos.length,
46+
message: `Successfully fetched ${allTodos.length} todos`,
47+
});
48+
49+
console.log("Todos fetch successful:", debugInfo);
50+
return NextResponse.json({
51+
success: true,
52+
data: allTodos,
53+
debug: debugInfo,
54+
});
2455
} catch (error) {
25-
console.error("Detailed error in todos fetch:", {
56+
const errorInfo = {
2657
message: error instanceof Error ? error.message : String(error),
58+
name: error instanceof Error ? error.name : "Unknown",
2759
stack: error instanceof Error ? error.stack : undefined,
28-
name: error instanceof Error ? error.name : undefined,
29-
});
60+
code: (error as any)?.code,
61+
detail: (error as any)?.detail,
62+
hint: (error as any)?.hint,
63+
};
64+
65+
debugInfo.error = errorInfo;
66+
67+
console.error("Detailed error in todos fetch:", debugInfo);
3068

3169
return NextResponse.json(
3270
{
71+
success: false,
3372
error: "Failed to fetch todos",
34-
details: error instanceof Error ? error.message : String(error),
73+
message: errorInfo.message,
74+
debug: debugInfo,
75+
details: errorInfo,
3576
},
3677
{ status: 500 }
3778
);
@@ -40,24 +81,81 @@ export async function GET() {
4081

4182
// POST /api/todos - Create a new todo
4283
export async function POST(request: Request) {
84+
const debugInfo: any = {
85+
timestamp: new Date().toISOString(),
86+
steps: [],
87+
};
88+
4389
try {
90+
debugInfo.steps.push({ step: 1, action: "Parsing request body" });
4491
const body = await request.json();
4592
const { title } = body;
4693

4794
if (!title || typeof title !== "string") {
48-
return NextResponse.json({ error: "Title is required" }, { status: 400 });
95+
return NextResponse.json(
96+
{
97+
success: false,
98+
error: "Title is required and must be a string",
99+
debug: debugInfo,
100+
},
101+
{ status: 400 }
102+
);
49103
}
50104

105+
debugInfo.steps.push({
106+
step: 1,
107+
result: "success",
108+
title: title.trim(),
109+
message: "Request body parsed successfully",
110+
});
111+
112+
debugInfo.steps.push({
113+
step: 2,
114+
action: "Inserting new todo into database",
115+
});
51116
const [newTodo] = await db
52117
.insert(todos)
53118
.values({ title: title.trim() })
54119
.returning();
55120

56-
return NextResponse.json(newTodo, { status: 201 });
121+
debugInfo.steps.push({
122+
step: 2,
123+
result: "success",
124+
todoId: newTodo.id,
125+
message: `Todo created with ID ${newTodo.id}`,
126+
});
127+
128+
console.log("Todo creation successful:", debugInfo);
129+
return NextResponse.json(
130+
{
131+
success: true,
132+
data: newTodo,
133+
debug: debugInfo,
134+
},
135+
{ status: 201 }
136+
);
57137
} catch (error) {
58-
console.error("Failed to create todo:", error);
138+
const errorInfo = {
139+
message: error instanceof Error ? error.message : String(error),
140+
name: error instanceof Error ? error.name : "Unknown",
141+
stack: error instanceof Error ? error.stack : undefined,
142+
code: (error as any)?.code,
143+
detail: (error as any)?.detail,
144+
hint: (error as any)?.hint,
145+
};
146+
147+
debugInfo.error = errorInfo;
148+
149+
console.error("Detailed error in todo creation:", debugInfo);
150+
59151
return NextResponse.json(
60-
{ error: "Failed to create todo" },
152+
{
153+
success: false,
154+
error: "Failed to create todo",
155+
message: errorInfo.message,
156+
debug: debugInfo,
157+
details: errorInfo,
158+
},
61159
{ status: 500 }
62160
);
63161
}

0 commit comments

Comments
 (0)