import { NextRequest } from "next/server"; import { errorResponse } from "./responseHandlers"; import { ValidationResult, ApiHandler, ApiHandlerBodyOnly, ApiHandlerWithRequest } from "./types"; /** * Safely parse JSON request body with error handling * @param request NextRequest object * @returns Parsed request body or null if parsing fails */ export async function parseRequestBody(request: NextRequest) { try { return await request.json(); } catch (error) { return null; } } /** * Wrapper for API route handlers with built-in error handling * @param handler The handler function to wrap */ export function withErrorHandling( handler: ApiHandler ) { return async (request: NextRequest) => { try { const body = await parseRequestBody(request); if (body === null) { return errorResponse("Invalid request body", 400); } // Check handler parameter count to determine if it needs request object // If handler has only 1 parameter, it's likely a create operation that only needs body if (handler.length === 1) { // Cast to the appropriate handler type return await (handler as ApiHandlerBodyOnly)(body); } else { // Otherwise pass both request and body (for list, update, delete operations) return await (handler as ApiHandlerWithRequest)(request, body); } } catch (error: any) { return errorResponse( error.message || "Internal Server Error", error.status || 500 ); } }; } /** * Validate that required fields are present in the request body * @param body Request body * @param requiredFields Array of required field names * @returns Object with validation result and error message if validation fails */ export function validateRequiredFields(body: any, requiredFields: string[]): ValidationResult { const missingFields = requiredFields.filter(field => body[field] === undefined || body[field] === null || body[field] === '' ); if (missingFields.length > 0) { return { valid: false, error: `Missing required fields: ${missingFields.join(', ')}` }; } return { valid: true }; }