withRouting( api: __DIR__.'/../routes/api.php', commands: __DIR__.'/../routes/console.php', health: '/up', apiPrefix: 'api/v1', ) ->withMiddleware(function (Middleware $middleware): void { // API uses token-based auth, no CSRF needed $middleware->alias([ 'portal.token' => \App\Http\Middleware\PortalTokenMiddleware::class, ]); }) ->withExceptions(function (Exceptions $exceptions): void { // Database connection / query errors → 503 $exceptions->render(function (QueryException|PDOException $e, Request $request) { if ($request->expectsJson() || $request->is('api/*')) { Log::error('Database error', [ 'exception' => get_class($e), 'message' => $e->getMessage(), 'trace' => $e->getTraceAsString(), ]); $response = ['message' => 'Service temporarily unavailable. Please try again later.']; if (config('app.debug')) { $response['debug'] = [ 'exception' => get_class($e), 'message' => $e->getMessage(), ]; } return response()->json($response, 503); } }); // 404 Not Found → friendly message $exceptions->render(function (NotFoundHttpException $e, Request $request) { if ($request->expectsJson() || $request->is('api/*')) { return response()->json([ 'message' => 'Resource not found.', ], 404); } }); // All other unhandled exceptions → 500 // (ValidationException, AuthenticationException, and HttpException are handled by Laravel) $exceptions->render(function (Throwable $e, Request $request) { if ($request->expectsJson() || $request->is('api/*')) { if ($e instanceof ValidationException || $e instanceof AuthenticationException || $e instanceof HttpException) { return null; // Let Laravel handle these normally } Log::error('Unhandled exception', [ 'exception' => get_class($e), 'message' => $e->getMessage(), 'trace' => $e->getTraceAsString(), ]); $response = ['message' => 'An unexpected error occurred.']; if (config('app.debug')) { $response['debug'] = [ 'exception' => get_class($e), 'message' => $e->getMessage(), ]; } return response()->json($response, 500); } }); })->create();