]> BookStack Code Mirror - bookstack/blob - app/Exceptions/Handler.php
63b5cfc5ae314a74a554001bfdfab8dad6a44e21
[bookstack] / app / Exceptions / Handler.php
1 <?php
2
3 namespace BookStack\Exceptions;
4
5 use Exception;
6 use Illuminate\Auth\AuthenticationException;
7 use Illuminate\Foundation\Exceptions\Handler as ExceptionHandler;
8 use Illuminate\Http\JsonResponse;
9 use Illuminate\Http\Request;
10 use Illuminate\Validation\ValidationException;
11 use Symfony\Component\HttpKernel\Exception\HttpException;
12 use Throwable;
13
14 class Handler extends ExceptionHandler
15 {
16     /**
17      * A list of the exception types that are not reported.
18      *
19      * @var array
20      */
21     protected $dontReport = [
22         NotFoundException::class,
23     ];
24
25     /**
26      * A list of the inputs that are never flashed for validation exceptions.
27      *
28      * @var array
29      */
30     protected $dontFlash = [
31         'password',
32         'password_confirmation',
33     ];
34
35     /**
36      * Report or log an exception.
37      *
38      * @param \Throwable $exception
39      *
40      * @throws \Throwable
41      *
42      * @return void
43      */
44     public function report(Throwable $exception)
45     {
46         parent::report($exception);
47     }
48
49     /**
50      * Render an exception into an HTTP response.
51      *
52      * @param \Illuminate\Http\Request $request
53      * @param Exception                $e
54      *
55      * @return \Illuminate\Http\Response
56      */
57     public function render($request, Throwable $e)
58     {
59         if ($this->isApiRequest($request)) {
60             return $this->renderApiException($e);
61         }
62
63         return parent::render($request, $e);
64     }
65
66     /**
67      * Check if the given request is an API request.
68      */
69     protected function isApiRequest(Request $request): bool
70     {
71         return strpos($request->path(), 'api/') === 0;
72     }
73
74     /**
75      * Render an exception when the API is in use.
76      */
77     protected function renderApiException(Exception $e): JsonResponse
78     {
79         $code = $e->getCode() === 0 ? 500 : $e->getCode();
80         $headers = [];
81         if ($e instanceof HttpException) {
82             $code = $e->getStatusCode();
83             $headers = $e->getHeaders();
84         }
85
86         $responseData = [
87             'error' => [
88                 'message' => $e->getMessage(),
89             ],
90         ];
91
92         if ($e instanceof ValidationException) {
93             $responseData['error']['validation'] = $e->errors();
94             $code = $e->status;
95         }
96
97         $responseData['error']['code'] = $code;
98
99         return new JsonResponse($responseData, $code, $headers);
100     }
101
102     /**
103      * Convert an authentication exception into an unauthenticated response.
104      *
105      * @param \Illuminate\Http\Request                 $request
106      * @param \Illuminate\Auth\AuthenticationException $exception
107      *
108      * @return \Illuminate\Http\Response
109      */
110     protected function unauthenticated($request, AuthenticationException $exception)
111     {
112         if ($request->expectsJson()) {
113             return response()->json(['error' => 'Unauthenticated.'], 401);
114         }
115
116         return redirect()->guest('login');
117     }
118
119     /**
120      * Convert a validation exception into a JSON response.
121      *
122      * @param \Illuminate\Http\Request                   $request
123      * @param \Illuminate\Validation\ValidationException $exception
124      *
125      * @return \Illuminate\Http\JsonResponse
126      */
127     protected function invalidJson($request, ValidationException $exception)
128     {
129         return response()->json($exception->errors(), $exception->status);
130     }
131 }