| 
									
										
										
										
											2015-07-13 03:01:42 +08:00
										 |  |  | <?php | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-09-11 02:31:09 +08:00
										 |  |  | namespace BookStack\Exceptions; | 
					
						
							| 
									
										
										
										
											2015-07-13 03:01:42 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | use Exception; | 
					
						
							| 
									
										
										
										
											2017-01-26 03:35:40 +08:00
										 |  |  | use Illuminate\Auth\AuthenticationException; | 
					
						
							| 
									
										
										
										
											2021-11-30 08:06:17 +08:00
										 |  |  | use Illuminate\Database\Eloquent\ModelNotFoundException; | 
					
						
							| 
									
										
										
										
											2015-07-13 03:01:42 +08:00
										 |  |  | use Illuminate\Foundation\Exceptions\Handler as ExceptionHandler; | 
					
						
							| 
									
										
										
										
											2023-09-25 20:48:23 +08:00
										 |  |  | use Illuminate\Http\Exceptions\PostTooLargeException; | 
					
						
							| 
									
										
										
										
											2020-01-18 23:03:28 +08:00
										 |  |  | use Illuminate\Http\JsonResponse; | 
					
						
							|  |  |  | use Illuminate\Http\Request; | 
					
						
							| 
									
										
										
										
											2018-09-25 23:58:03 +08:00
										 |  |  | use Illuminate\Validation\ValidationException; | 
					
						
							| 
									
										
										
										
											2023-09-29 20:54:08 +08:00
										 |  |  | use Symfony\Component\ErrorHandler\Error\FatalError; | 
					
						
							| 
									
										
										
										
											2023-06-14 00:40:37 +08:00
										 |  |  | use Symfony\Component\HttpKernel\Exception\HttpExceptionInterface; | 
					
						
							| 
									
										
										
										
											2021-10-27 05:04:18 +08:00
										 |  |  | use Throwable; | 
					
						
							| 
									
										
										
										
											2015-07-13 03:01:42 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | class Handler extends ExceptionHandler | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     /** | 
					
						
							| 
									
										
										
										
											2021-03-03 05:59:12 +08:00
										 |  |  |      * A list of the exception types that are not reported. | 
					
						
							| 
									
										
										
										
											2015-07-13 03:01:42 +08:00
										 |  |  |      * | 
					
						
							| 
									
										
										
										
											2023-02-07 00:58:29 +08:00
										 |  |  |      * @var array<int, class-string<\Throwable>> | 
					
						
							| 
									
										
										
										
											2015-07-13 03:01:42 +08:00
										 |  |  |      */ | 
					
						
							|  |  |  |     protected $dontReport = [ | 
					
						
							| 
									
										
										
										
											2020-05-23 18:26:48 +08:00
										 |  |  |         NotFoundException::class, | 
					
						
							| 
									
										
										
										
											2022-05-31 01:31:08 +08:00
										 |  |  |         StoppedAuthenticationException::class, | 
					
						
							| 
									
										
										
										
											2015-07-13 03:01:42 +08:00
										 |  |  |     ]; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-03-03 05:59:12 +08:00
										 |  |  |     /** | 
					
						
							| 
									
										
										
										
											2023-02-07 00:58:29 +08:00
										 |  |  |      * A list of the inputs that are never flashed to the session on validation exceptions. | 
					
						
							| 
									
										
										
										
											2021-03-03 05:59:12 +08:00
										 |  |  |      * | 
					
						
							| 
									
										
										
										
											2023-02-07 00:58:29 +08:00
										 |  |  |      * @var array<int, string> | 
					
						
							| 
									
										
										
										
											2021-03-03 05:59:12 +08:00
										 |  |  |      */ | 
					
						
							|  |  |  |     protected $dontFlash = [ | 
					
						
							| 
									
										
										
										
											2021-10-31 04:29:59 +08:00
										 |  |  |         'current_password', | 
					
						
							| 
									
										
										
										
											2021-03-03 05:59:12 +08:00
										 |  |  |         'password', | 
					
						
							|  |  |  |         'password_confirmation', | 
					
						
							|  |  |  |     ]; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-09-29 20:54:08 +08:00
										 |  |  |     /** | 
					
						
							|  |  |  |      * A function to run upon out of memory. | 
					
						
							|  |  |  |      * If it returns a response, that will be provided back to the request | 
					
						
							|  |  |  |      * upon an out of memory event. | 
					
						
							|  |  |  |      * | 
					
						
							|  |  |  |      * @var ?callable<?\Illuminate\Http\Response> | 
					
						
							|  |  |  |      */ | 
					
						
							|  |  |  |     protected $onOutOfMemory = null; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-07-13 03:01:42 +08:00
										 |  |  |     /** | 
					
						
							|  |  |  |      * Report or log an exception. | 
					
						
							|  |  |  |      * | 
					
						
							| 
									
										
										
										
											2021-10-27 05:04:18 +08:00
										 |  |  |      * @param \Throwable $exception | 
					
						
							| 
									
										
										
										
											2021-03-03 05:59:12 +08:00
										 |  |  |      * | 
					
						
							| 
									
										
										
										
											2021-10-27 05:04:18 +08:00
										 |  |  |      * @throws \Throwable | 
					
						
							| 
									
										
										
										
											2021-06-26 23:23:15 +08:00
										 |  |  |      * | 
					
						
							|  |  |  |      * @return void | 
					
						
							| 
									
										
										
										
											2015-07-13 03:01:42 +08:00
										 |  |  |      */ | 
					
						
							| 
									
										
										
										
											2021-10-27 05:04:18 +08:00
										 |  |  |     public function report(Throwable $exception) | 
					
						
							| 
									
										
										
										
											2015-07-13 03:01:42 +08:00
										 |  |  |     { | 
					
						
							| 
									
										
										
										
											2021-03-03 05:59:12 +08:00
										 |  |  |         parent::report($exception); | 
					
						
							| 
									
										
										
										
											2015-07-13 03:01:42 +08:00
										 |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     /** | 
					
						
							|  |  |  |      * Render an exception into an HTTP response. | 
					
						
							|  |  |  |      * | 
					
						
							| 
									
										
										
										
											2021-06-26 23:23:15 +08:00
										 |  |  |      * @param \Illuminate\Http\Request $request | 
					
						
							|  |  |  |      * @param Exception                $e | 
					
						
							|  |  |  |      * | 
					
						
							| 
									
										
										
										
											2015-07-13 03:01:42 +08:00
										 |  |  |      * @return \Illuminate\Http\Response | 
					
						
							|  |  |  |      */ | 
					
						
							| 
									
										
										
										
											2021-10-27 05:04:18 +08:00
										 |  |  |     public function render($request, Throwable $e) | 
					
						
							| 
									
										
										
										
											2015-07-13 03:01:42 +08:00
										 |  |  |     { | 
					
						
							| 
									
										
										
										
											2023-09-29 20:54:08 +08:00
										 |  |  |         if ($e instanceof FatalError && str_contains($e->getMessage(), 'bytes exhausted (tried to allocate') && $this->onOutOfMemory) { | 
					
						
							|  |  |  |             $response = call_user_func($this->onOutOfMemory); | 
					
						
							|  |  |  |             if ($response) { | 
					
						
							|  |  |  |                 return $response; | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-09-25 20:48:23 +08:00
										 |  |  |         if ($e instanceof PostTooLargeException) { | 
					
						
							|  |  |  |             $e = new NotifyException(trans('errors.server_post_limit'), '/', 413); | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-01-18 23:03:28 +08:00
										 |  |  |         if ($this->isApiRequest($request)) { | 
					
						
							|  |  |  |             return $this->renderApiException($e); | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-07-13 03:01:42 +08:00
										 |  |  |         return parent::render($request, $e); | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2016-09-03 19:08:58 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-09-29 20:54:08 +08:00
										 |  |  |     /** | 
					
						
							|  |  |  |      * Provide a function to be called when an out of memory event occurs. | 
					
						
							|  |  |  |      * If the callable returns a response, this response will be returned | 
					
						
							|  |  |  |      * to the request upon error. | 
					
						
							|  |  |  |      */ | 
					
						
							|  |  |  |     public function prepareForOutOfMemory(callable $onOutOfMemory) | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |         $this->onOutOfMemory = $onOutOfMemory; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     /** | 
					
						
							|  |  |  |      * Forget the current out of memory handler, if existing. | 
					
						
							|  |  |  |      */ | 
					
						
							|  |  |  |     public function forgetOutOfMemoryHandler() | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |         $this->onOutOfMemory = null; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-01-18 23:03:28 +08:00
										 |  |  |     /** | 
					
						
							|  |  |  |      * Check if the given request is an API request. | 
					
						
							|  |  |  |      */ | 
					
						
							|  |  |  |     protected function isApiRequest(Request $request): bool | 
					
						
							|  |  |  |     { | 
					
						
							| 
									
										
										
										
											2023-09-25 20:48:23 +08:00
										 |  |  |         return str_starts_with($request->path(), 'api/'); | 
					
						
							| 
									
										
										
										
											2020-01-18 23:03:28 +08:00
										 |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     /** | 
					
						
							|  |  |  |      * Render an exception when the API is in use. | 
					
						
							|  |  |  |      */ | 
					
						
							| 
									
										
										
										
											2021-11-30 08:06:17 +08:00
										 |  |  |     protected function renderApiException(Throwable $e): JsonResponse | 
					
						
							| 
									
										
										
										
											2020-01-18 23:03:28 +08:00
										 |  |  |     { | 
					
						
							| 
									
										
										
										
											2023-06-14 00:40:37 +08:00
										 |  |  |         $code = 500; | 
					
						
							| 
									
										
										
										
											2020-01-18 23:03:28 +08:00
										 |  |  |         $headers = []; | 
					
						
							| 
									
										
										
										
											2021-11-30 08:06:17 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-06-14 00:40:37 +08:00
										 |  |  |         if ($e instanceof HttpExceptionInterface) { | 
					
						
							| 
									
										
										
										
											2020-01-18 23:03:28 +08:00
										 |  |  |             $code = $e->getStatusCode(); | 
					
						
							|  |  |  |             $headers = $e->getHeaders(); | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-11-30 08:06:17 +08:00
										 |  |  |         if ($e instanceof ModelNotFoundException) { | 
					
						
							|  |  |  |             $code = 404; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-01-18 23:03:28 +08:00
										 |  |  |         $responseData = [ | 
					
						
							|  |  |  |             'error' => [ | 
					
						
							|  |  |  |                 'message' => $e->getMessage(), | 
					
						
							| 
									
										
										
										
											2021-06-26 23:23:15 +08:00
										 |  |  |             ], | 
					
						
							| 
									
										
										
										
											2020-01-18 23:03:28 +08:00
										 |  |  |         ]; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         if ($e instanceof ValidationException) { | 
					
						
							| 
									
										
										
										
											2023-02-07 04:41:33 +08:00
										 |  |  |             $responseData['error']['message'] = 'The given data was invalid.'; | 
					
						
							| 
									
										
										
										
											2020-01-18 23:03:28 +08:00
										 |  |  |             $responseData['error']['validation'] = $e->errors(); | 
					
						
							|  |  |  |             $code = $e->status; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         $responseData['error']['code'] = $code; | 
					
						
							| 
									
										
										
										
											2021-06-26 23:23:15 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-01-18 23:03:28 +08:00
										 |  |  |         return new JsonResponse($responseData, $code, $headers); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-09-18 01:22:04 +08:00
										 |  |  |     /** | 
					
						
							|  |  |  |      * Convert an authentication exception into an unauthenticated response. | 
					
						
							|  |  |  |      * | 
					
						
							| 
									
										
										
										
											2021-06-26 23:23:15 +08:00
										 |  |  |      * @param \Illuminate\Http\Request                 $request | 
					
						
							|  |  |  |      * @param \Illuminate\Auth\AuthenticationException $exception | 
					
						
							|  |  |  |      * | 
					
						
							| 
									
										
										
										
											2016-09-18 01:22:04 +08:00
										 |  |  |      * @return \Illuminate\Http\Response | 
					
						
							|  |  |  |      */ | 
					
						
							|  |  |  |     protected function unauthenticated($request, AuthenticationException $exception) | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |         if ($request->expectsJson()) { | 
					
						
							|  |  |  |             return response()->json(['error' => 'Unauthenticated.'], 401); | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         return redirect()->guest('login'); | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2017-11-19 23:56:06 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  |     /** | 
					
						
							|  |  |  |      * Convert a validation exception into a JSON response. | 
					
						
							|  |  |  |      * | 
					
						
							| 
									
										
										
										
											2021-06-26 23:23:15 +08:00
										 |  |  |      * @param \Illuminate\Http\Request                   $request | 
					
						
							|  |  |  |      * @param \Illuminate\Validation\ValidationException $exception | 
					
						
							|  |  |  |      * | 
					
						
							| 
									
										
										
										
											2017-11-19 23:56:06 +08:00
										 |  |  |      * @return \Illuminate\Http\JsonResponse | 
					
						
							|  |  |  |      */ | 
					
						
							|  |  |  |     protected function invalidJson($request, ValidationException $exception) | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |         return response()->json($exception->errors(), $exception->status); | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2015-07-13 03:01:42 +08:00
										 |  |  | } |