| 
									
										
										
										
											2016-01-08 16:02:15 +01:00
										 |  |  | <?php | 
					
						
							| 
									
										
										
										
											2018-05-11 10:08:34 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-10-21 08:40:00 +02:00
										 |  |  | /** | 
					
						
							|  |  |  |  * Handler.php | 
					
						
							| 
									
										
										
										
											2020-01-28 08:44:57 +01:00
										 |  |  |  * Copyright (c) 2019 james@firefly-iii.org | 
					
						
							| 
									
										
										
										
											2017-10-21 08:40:00 +02:00
										 |  |  |  * | 
					
						
							| 
									
										
										
										
											2019-10-02 06:37:26 +02:00
										 |  |  |  * This file is part of Firefly III (https://github.com/firefly-iii). | 
					
						
							| 
									
										
										
										
											2017-10-21 08:40:00 +02:00
										 |  |  |  * | 
					
						
							| 
									
										
										
										
											2019-10-02 06:37:26 +02:00
										 |  |  |  * This program is free software: you can redistribute it and/or modify | 
					
						
							|  |  |  |  * it under the terms of the GNU Affero General Public License as | 
					
						
							|  |  |  |  * published by the Free Software Foundation, either version 3 of the | 
					
						
							|  |  |  |  * License, or (at your option) any later version. | 
					
						
							| 
									
										
										
										
											2017-10-21 08:40:00 +02:00
										 |  |  |  * | 
					
						
							| 
									
										
										
										
											2019-10-02 06:37:26 +02:00
										 |  |  |  * This program is distributed in the hope that it will be useful, | 
					
						
							| 
									
										
										
										
											2017-10-21 08:40:00 +02:00
										 |  |  |  * but WITHOUT ANY WARRANTY; without even the implied warranty of | 
					
						
							|  |  |  |  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the | 
					
						
							| 
									
										
										
										
											2019-10-02 06:37:26 +02:00
										 |  |  |  * GNU Affero General Public License for more details. | 
					
						
							| 
									
										
										
										
											2017-10-21 08:40:00 +02:00
										 |  |  |  * | 
					
						
							| 
									
										
										
										
											2019-10-02 06:37:26 +02:00
										 |  |  |  * You should have received a copy of the GNU Affero General Public License | 
					
						
							|  |  |  |  * along with this program.  If not, see <https://www.gnu.org/licenses/>. | 
					
						
							| 
									
										
										
										
											2017-10-21 08:40:00 +02:00
										 |  |  |  */ | 
					
						
							| 
									
										
										
										
											2017-09-14 17:40:02 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-05-11 10:08:34 +02:00
										 |  |  | declare(strict_types=1); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-01-08 16:02:15 +01:00
										 |  |  | namespace FireflyIII\Exceptions; | 
					
						
							| 
									
										
										
										
											2015-02-06 04:39:52 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-05-27 17:02:18 +02:00
										 |  |  | use Carbon\Carbon; | 
					
						
							| 
									
										
										
										
											2025-01-26 06:30:38 +01:00
										 |  |  | use Brick\Math\Exception\NumberFormatException; | 
					
						
							| 
									
										
										
										
											2017-09-12 22:14:43 +02:00
										 |  |  | use FireflyIII\Jobs\MailError; | 
					
						
							| 
									
										
										
										
											2024-04-07 06:06:40 +02:00
										 |  |  | use Illuminate\Auth\Access\AuthorizationException; | 
					
						
							| 
									
										
										
										
											2018-02-17 14:14:26 +01:00
										 |  |  | use Illuminate\Auth\AuthenticationException; | 
					
						
							| 
									
										
										
										
											2022-06-10 06:00:01 +02:00
										 |  |  | use Illuminate\Database\QueryException; | 
					
						
							| 
									
										
										
										
											2016-01-08 16:02:15 +01:00
										 |  |  | use Illuminate\Foundation\Exceptions\Handler as ExceptionHandler; | 
					
						
							| 
									
										
										
										
											2023-11-05 10:16:53 +01:00
										 |  |  | use Illuminate\Http\JsonResponse; | 
					
						
							| 
									
										
										
										
											2021-10-02 13:28:56 +02:00
										 |  |  | use Illuminate\Http\RedirectResponse; | 
					
						
							| 
									
										
										
										
											2020-07-31 12:45:02 +02:00
										 |  |  | use Illuminate\Http\Request; | 
					
						
							| 
									
										
										
										
											2021-04-07 07:28:43 +02:00
										 |  |  | use Illuminate\Session\TokenMismatchException; | 
					
						
							| 
									
										
										
										
											2021-04-03 12:32:29 +02:00
										 |  |  | use Illuminate\Support\Arr; | 
					
						
							| 
									
										
										
										
											2018-07-15 10:00:08 +02:00
										 |  |  | use Illuminate\Validation\ValidationException as LaravelValidationException; | 
					
						
							| 
									
										
										
										
											2021-04-07 14:18:43 +02:00
										 |  |  | use Laravel\Passport\Exceptions\OAuthServerException as LaravelOAuthException; | 
					
						
							| 
									
										
										
										
											2021-05-28 23:11:12 +02:00
										 |  |  | use League\OAuth2\Server\Exception\OAuthServerException; | 
					
						
							| 
									
										
										
										
											2022-09-04 13:31:46 +02:00
										 |  |  | use Symfony\Component\HttpFoundation\Exception\SuspiciousOperationException; | 
					
						
							| 
									
										
										
										
											2023-11-05 10:16:53 +01:00
										 |  |  | use Symfony\Component\HttpFoundation\Response; | 
					
						
							| 
									
										
										
										
											2022-12-29 19:41:57 +01:00
										 |  |  | use Symfony\Component\HttpKernel\Exception\BadRequestHttpException; | 
					
						
							| 
									
										
										
										
											2021-04-08 06:50:00 +02:00
										 |  |  | use Symfony\Component\HttpKernel\Exception\HttpException; | 
					
						
							| 
									
										
										
										
											2022-06-23 09:33:43 +02:00
										 |  |  | use Symfony\Component\HttpKernel\Exception\MethodNotAllowedHttpException; | 
					
						
							| 
									
										
										
										
											2021-05-28 23:11:12 +02:00
										 |  |  | use Symfony\Component\HttpKernel\Exception\NotFoundHttpException; | 
					
						
							| 
									
										
										
										
											2025-05-27 16:57:36 +02:00
										 |  |  | use ErrorException; | 
					
						
							|  |  |  | use Override; | 
					
						
							|  |  |  | use Throwable; | 
					
						
							| 
									
										
										
										
											2025-05-11 13:12:26 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-05-27 17:02:18 +02:00
										 |  |  | use function Safe\json_encode; | 
					
						
							|  |  |  | use function Safe\parse_url; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-05-11 13:56:07 +02:00
										 |  |  | // temp
 | 
					
						
							| 
									
										
										
										
											2017-12-17 14:30:53 +01:00
										 |  |  | /** | 
					
						
							|  |  |  |  * Class Handler | 
					
						
							|  |  |  |  */ | 
					
						
							| 
									
										
										
										
											2025-05-11 14:01:01 +02:00
										 |  |  | class Handler extends ExceptionHandler | 
					
						
							| 
									
										
										
										
											2015-02-11 07:35:10 +01:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2025-06-12 15:36:38 +02:00
										 |  |  |     public static ?Throwable $lastError = null; | 
					
						
							| 
									
										
										
										
											2025-06-12 15:41:41 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-04-03 12:25:35 +02:00
										 |  |  |     /** | 
					
						
							| 
									
										
										
										
											2025-05-27 16:57:36 +02:00
										 |  |  |      * @var array<int, class-string<Throwable>> | 
					
						
							| 
									
										
										
										
											2021-04-03 12:25:35 +02:00
										 |  |  |      */ | 
					
						
							|  |  |  |     protected $dontReport | 
					
						
							| 
									
										
										
										
											2025-06-12 15:41:41 +02:00
										 |  |  |                                         = [ | 
					
						
							| 
									
										
										
										
											2021-04-03 13:19:11 +02:00
										 |  |  |             AuthenticationException::class, | 
					
						
							|  |  |  |             LaravelValidationException::class, | 
					
						
							| 
									
										
										
										
											2021-04-04 15:53:17 +02:00
										 |  |  |             NotFoundHttpException::class, | 
					
						
							| 
									
										
										
										
											2021-04-07 07:28:43 +02:00
										 |  |  |             OAuthServerException::class, | 
					
						
							| 
									
										
										
										
											2021-04-07 14:18:43 +02:00
										 |  |  |             LaravelOAuthException::class, | 
					
						
							| 
									
										
										
										
											2021-04-07 07:28:43 +02:00
										 |  |  |             TokenMismatchException::class, | 
					
						
							| 
									
										
										
										
											2021-05-28 23:11:12 +02:00
										 |  |  |             HttpException::class, | 
					
						
							| 
									
										
										
										
											2022-12-29 19:41:57 +01:00
										 |  |  |             SuspiciousOperationException::class, | 
					
						
							| 
									
										
										
										
											2023-01-08 16:34:34 +01:00
										 |  |  |             BadHttpHeaderException::class, | 
					
						
							| 
									
										
										
										
											2021-04-03 12:25:35 +02:00
										 |  |  |         ]; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-08-05 19:45:04 +02:00
										 |  |  |     /** | 
					
						
							|  |  |  |      * Register the exception handling callbacks for the application. | 
					
						
							|  |  |  |      */ | 
					
						
							| 
									
										
										
										
											2025-05-27 16:57:36 +02:00
										 |  |  |     #[Override]
 | 
					
						
							| 
									
										
										
										
											2024-12-28 10:58:01 +01:00
										 |  |  |     public function register(): void {} | 
					
						
							| 
									
										
										
										
											2024-08-05 19:45:04 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-02-11 14:17:11 +01:00
										 |  |  |     /** | 
					
						
							| 
									
										
										
										
											2023-12-22 20:12:38 +01:00
										 |  |  |      * Render an exception into an HTTP response. It's complex but lucky for us, we never use it because | 
					
						
							|  |  |  |      * Firefly III never crashes. | 
					
						
							| 
									
										
										
										
											2016-02-11 14:17:11 +01:00
										 |  |  |      * | 
					
						
							| 
									
										
										
										
											2023-12-20 19:35:52 +01:00
										 |  |  |      * @param Request $request | 
					
						
							| 
									
										
										
										
											2019-08-17 10:46:55 +02:00
										 |  |  |      * | 
					
						
							| 
									
										
										
										
											2025-05-27 16:57:36 +02:00
										 |  |  |      * @throws Throwable | 
					
						
							| 
									
										
										
										
											2023-12-22 20:12:38 +01:00
										 |  |  |      * | 
					
						
							| 
									
										
										
										
											2025-01-03 15:53:10 +01:00
										 |  |  |      * @SuppressWarnings("PHPMD.NPathComplexity") | 
					
						
							|  |  |  |      * @SuppressWarnings("PHPMD.CyclomaticComplexity") | 
					
						
							| 
									
										
										
										
											2016-02-11 14:17:11 +01:00
										 |  |  |      */ | 
					
						
							| 
									
										
										
										
											2025-05-27 16:57:36 +02:00
										 |  |  |     #[Override]
 | 
					
						
							|  |  |  |     public function render($request, Throwable $e): Response | 
					
						
							| 
									
										
										
										
											2016-02-11 14:17:11 +01:00
										 |  |  |     { | 
					
						
							| 
									
										
										
										
											2023-01-11 08:13:52 +01:00
										 |  |  |         $expectsJson = $request->expectsJson(); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-10-29 06:33:43 +01:00
										 |  |  |         app('log')->debug('Now in Handler::render()'); | 
					
						
							| 
									
										
										
										
											2024-08-05 19:45:04 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-01-11 08:13:52 +01:00
										 |  |  |         if ($e instanceof LaravelValidationException && $expectsJson) { | 
					
						
							| 
									
										
										
										
											2018-02-13 18:24:06 +01:00
										 |  |  |             // ignore it: controller will handle it.
 | 
					
						
							| 
									
										
										
										
											2024-08-05 19:45:04 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-10-29 06:33:43 +01:00
										 |  |  |             app('log')->debug(sprintf('Return to parent to handle LaravelValidationException(%d)', $e->status)); | 
					
						
							| 
									
										
										
										
											2023-12-20 19:35:52 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-04-03 13:19:11 +02:00
										 |  |  |             return parent::render($request, $e); | 
					
						
							| 
									
										
										
										
											2018-02-13 18:24:06 +01:00
										 |  |  |         } | 
					
						
							| 
									
										
										
										
											2023-01-11 08:13:52 +01:00
										 |  |  |         if ($e instanceof NotFoundHttpException && $expectsJson) { | 
					
						
							| 
									
										
										
										
											2018-03-07 05:51:51 +01:00
										 |  |  |             // JSON error:
 | 
					
						
							| 
									
										
										
										
											2023-10-29 06:33:43 +01:00
										 |  |  |             app('log')->debug('Return JSON not found error.'); | 
					
						
							| 
									
										
										
										
											2023-12-20 19:35:52 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-02-11 20:45:33 +01:00
										 |  |  |             return response()->json(['message' => 'Resource not found', 'exception' => 'NotFoundHttpException'], 404); | 
					
						
							|  |  |  |         } | 
					
						
							| 
									
										
										
										
											2018-02-17 14:14:26 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-04-07 06:06:40 +02:00
										 |  |  |         if ($e instanceof AuthorizationException && $expectsJson) { | 
					
						
							|  |  |  |             // somehow Laravel handler does not catch this:
 | 
					
						
							|  |  |  |             app('log')->debug('Return JSON unauthorized error.'); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             return response()->json(['message' => $e->getMessage(), 'exception' => 'AuthorizationException'], 401); | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-01-11 08:13:52 +01:00
										 |  |  |         if ($e instanceof AuthenticationException && $expectsJson) { | 
					
						
							| 
									
										
										
										
											2018-03-07 05:51:51 +01:00
										 |  |  |             // somehow Laravel handler does not catch this:
 | 
					
						
							| 
									
										
										
										
											2023-10-29 06:33:43 +01:00
										 |  |  |             app('log')->debug('Return JSON unauthenticated error.'); | 
					
						
							| 
									
										
										
										
											2023-12-20 19:35:52 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-06-12 15:36:38 +02:00
										 |  |  |             return response()->json(['message' => $e->getMessage(), 'exception' => 'AuthenticationException'], 401); | 
					
						
							| 
									
										
										
										
											2018-02-17 14:14:26 +01:00
										 |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-01-11 08:13:52 +01:00
										 |  |  |         if ($e instanceof OAuthServerException && $expectsJson) { | 
					
						
							| 
									
										
										
										
											2023-10-29 06:33:43 +01:00
										 |  |  |             app('log')->debug('Return JSON OAuthServerException.'); | 
					
						
							| 
									
										
										
										
											2023-12-20 19:35:52 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-05-10 09:48:13 +02:00
										 |  |  |             // somehow Laravel handler does not catch this:
 | 
					
						
							| 
									
										
										
										
											2021-04-03 13:19:11 +02:00
										 |  |  |             return response()->json(['message' => $e->getMessage(), 'exception' => 'OAuthServerException'], 401); | 
					
						
							| 
									
										
										
										
											2018-05-10 09:48:13 +02:00
										 |  |  |         } | 
					
						
							| 
									
										
										
										
											2022-10-30 14:24:10 +01:00
										 |  |  |         if ($e instanceof BadRequestHttpException) { | 
					
						
							| 
									
										
										
										
											2023-10-29 06:33:43 +01:00
										 |  |  |             app('log')->debug('Return JSON BadRequestHttpException.'); | 
					
						
							| 
									
										
										
										
											2023-12-20 19:35:52 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-01-25 04:50:15 +01:00
										 |  |  |             return response()->json(['message' => $e->getMessage(), 'exception' => 'HttpException'], 400); | 
					
						
							| 
									
										
										
										
											2022-06-23 09:33:43 +02:00
										 |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         if ($e instanceof BadHttpHeaderException) { | 
					
						
							|  |  |  |             // is always API exception.
 | 
					
						
							| 
									
										
										
										
											2023-10-29 06:33:43 +01:00
										 |  |  |             app('log')->debug('Return JSON BadHttpHeaderException.'); | 
					
						
							| 
									
										
										
										
											2023-12-20 19:35:52 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-06-23 09:33:43 +02:00
										 |  |  |             return response()->json(['message' => $e->getMessage(), 'exception' => 'BadHttpHeaderException'], $e->statusCode); | 
					
						
							|  |  |  |         } | 
					
						
							| 
									
										
										
										
											2025-01-26 14:33:19 +01:00
										 |  |  |         if (($e instanceof ValidationException || $e instanceof NumberFormatException) && $expectsJson) { | 
					
						
							| 
									
										
										
										
											2025-01-25 09:17:21 +01:00
										 |  |  |             $errorCode = 422; | 
					
						
							| 
									
										
										
										
											2025-01-26 14:33:19 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-01-25 09:17:21 +01:00
										 |  |  |             return response()->json( | 
					
						
							| 
									
										
										
										
											2025-01-26 06:30:38 +01:00
										 |  |  |                 ['message' => sprintf('Validation exception: %s', $e->getMessage()), 'errors' => ['field' => 'Field is invalid']], | 
					
						
							| 
									
										
										
										
											2025-01-25 09:17:21 +01:00
										 |  |  |                 $errorCode | 
					
						
							|  |  |  |             ); | 
					
						
							|  |  |  |         } | 
					
						
							| 
									
										
										
										
											2018-05-10 09:48:13 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-01-11 08:13:52 +01:00
										 |  |  |         if ($expectsJson) { | 
					
						
							| 
									
										
										
										
											2022-06-23 09:33:43 +02:00
										 |  |  |             $errorCode = 500; | 
					
						
							| 
									
										
										
										
											2022-10-30 14:24:10 +01:00
										 |  |  |             $errorCode = $e instanceof MethodNotAllowedHttpException ? 405 : $errorCode; | 
					
						
							| 
									
										
										
										
											2022-06-23 09:33:43 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-12-22 08:43:12 +01:00
										 |  |  |             $isDebug   = (bool) config('app.debug', false); | 
					
						
							| 
									
										
										
										
											2018-02-11 20:45:33 +01:00
										 |  |  |             if ($isDebug) { | 
					
						
							| 
									
										
										
										
											2025-05-04 12:57:14 +02:00
										 |  |  |                 app('log')->debug(sprintf('Return JSON %s with debug.', $e::class)); | 
					
						
							| 
									
										
										
										
											2023-12-20 19:35:52 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-02-11 20:45:33 +01:00
										 |  |  |                 return response()->json( | 
					
						
							|  |  |  |                     [ | 
					
						
							| 
									
										
										
										
											2021-04-03 13:19:11 +02:00
										 |  |  |                         'message'   => $e->getMessage(), | 
					
						
							| 
									
										
										
										
											2025-05-04 12:57:14 +02:00
										 |  |  |                         'exception' => $e::class, | 
					
						
							| 
									
										
										
										
											2021-04-03 13:19:11 +02:00
										 |  |  |                         'line'      => $e->getLine(), | 
					
						
							|  |  |  |                         'file'      => $e->getFile(), | 
					
						
							|  |  |  |                         'trace'     => $e->getTrace(), | 
					
						
							| 
									
										
										
										
											2020-03-17 14:57:04 +01:00
										 |  |  |                     ], | 
					
						
							| 
									
										
										
										
											2022-06-23 09:33:43 +02:00
										 |  |  |                     $errorCode | 
					
						
							| 
									
										
										
										
											2018-02-11 20:45:33 +01:00
										 |  |  |                 ); | 
					
						
							|  |  |  |             } | 
					
						
							| 
									
										
										
										
											2025-05-04 12:57:14 +02:00
										 |  |  |             app('log')->debug(sprintf('Return JSON %s.', $e::class)); | 
					
						
							| 
									
										
										
										
											2023-12-20 19:35:52 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-03-21 09:15:40 +01:00
										 |  |  |             return response()->json( | 
					
						
							| 
									
										
										
										
											2025-01-25 04:50:15 +01:00
										 |  |  |                 ['message' => sprintf('Internal Firefly III Exception: %s', $e->getMessage()), 'exception' => 'UndisclosedException'], | 
					
						
							| 
									
										
										
										
											2022-06-23 09:33:43 +02:00
										 |  |  |                 $errorCode | 
					
						
							| 
									
										
										
										
											2021-03-21 09:15:40 +01:00
										 |  |  |             ); | 
					
						
							| 
									
										
										
										
											2018-02-10 09:57:56 +01:00
										 |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-04-03 13:19:11 +02:00
										 |  |  |         if ($e instanceof NotFoundHttpException) { | 
					
						
							| 
									
										
										
										
											2023-10-29 06:33:43 +01:00
										 |  |  |             app('log')->debug('Refer to GracefulNotFoundHandler'); | 
					
						
							| 
									
										
										
										
											2019-08-01 06:22:07 +02:00
										 |  |  |             $handler = app(GracefulNotFoundHandler::class); | 
					
						
							| 
									
										
										
										
											2020-03-17 14:57:04 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-04-03 13:19:11 +02:00
										 |  |  |             return $handler->render($request, $e); | 
					
						
							| 
									
										
										
										
											2019-08-01 06:22:07 +02:00
										 |  |  |         } | 
					
						
							| 
									
										
										
										
											2017-09-12 22:14:43 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-06-10 06:00:01 +02:00
										 |  |  |         // special view for database errors with extra instructions
 | 
					
						
							| 
									
										
										
										
											2022-10-30 14:24:10 +01:00
										 |  |  |         if ($e instanceof QueryException) { | 
					
						
							| 
									
										
										
										
											2023-10-29 06:33:43 +01:00
										 |  |  |             app('log')->debug('Return Firefly III database exception view.'); | 
					
						
							| 
									
										
										
										
											2022-06-10 06:00:01 +02:00
										 |  |  |             $isDebug = config('app.debug'); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             return response()->view('errors.DatabaseException', ['exception' => $e, 'debug' => $isDebug], 500); | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-05-27 16:57:36 +02:00
										 |  |  |         if ($e instanceof FireflyException || $e instanceof ErrorException || $e instanceof OAuthServerException) { | 
					
						
							| 
									
										
										
										
											2023-10-29 06:33:43 +01:00
										 |  |  |             app('log')->debug('Return Firefly III error view.'); | 
					
						
							| 
									
										
										
										
											2023-01-11 08:13:52 +01:00
										 |  |  |             $isDebug = config('app.debug'); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             return response()->view('errors.FireflyException', ['exception' => $e, 'debug' => $isDebug], 500); | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-05-04 12:57:14 +02:00
										 |  |  |         app('log')->debug(sprintf('Error "%s" has no Firefly III treatment, parent will handle.', $e::class)); | 
					
						
							| 
									
										
										
										
											2017-09-12 22:14:43 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-04-03 13:19:11 +02:00
										 |  |  |         return parent::render($request, $e); | 
					
						
							| 
									
										
										
										
											2015-02-11 07:35:10 +01:00
										 |  |  |     } | 
					
						
							| 
									
										
										
										
											2016-09-16 06:40:45 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |     /** | 
					
						
							| 
									
										
										
										
											2017-09-12 22:14:43 +02:00
										 |  |  |      * Report or log an exception. | 
					
						
							| 
									
										
										
										
											2016-10-07 05:44:21 +02:00
										 |  |  |      * | 
					
						
							| 
									
										
										
										
											2025-05-27 16:57:36 +02:00
										 |  |  |      * @throws Throwable | 
					
						
							| 
									
										
										
										
											2016-09-16 06:40:45 +02:00
										 |  |  |      */ | 
					
						
							| 
									
										
										
										
											2025-05-27 16:57:36 +02:00
										 |  |  |     #[Override]
 | 
					
						
							|  |  |  |     public function report(Throwable $e): void | 
					
						
							| 
									
										
										
										
											2016-09-16 06:40:45 +02:00
										 |  |  |     { | 
					
						
							| 
									
										
										
										
											2025-06-12 15:36:38 +02:00
										 |  |  |         self::$lastError = $e; | 
					
						
							| 
									
										
										
										
											2025-06-12 15:41:41 +02:00
										 |  |  |         $doMailError     = (bool) config('firefly.send_error_message'); | 
					
						
							| 
									
										
										
										
											2021-04-03 12:32:29 +02:00
										 |  |  |         if ($this->shouldntReportLocal($e) || !$doMailError) { | 
					
						
							| 
									
										
										
										
											2021-04-03 12:25:35 +02:00
										 |  |  |             parent::report($e); | 
					
						
							| 
									
										
										
										
											2021-04-03 12:32:29 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-04-03 12:25:35 +02:00
										 |  |  |             return; | 
					
						
							| 
									
										
										
										
											2017-09-12 22:14:43 +02:00
										 |  |  |         } | 
					
						
							| 
									
										
										
										
											2025-06-12 15:41:41 +02:00
										 |  |  |         $userData        = [ | 
					
						
							| 
									
										
										
										
											2021-04-03 12:25:35 +02:00
										 |  |  |             'id'    => 0, | 
					
						
							|  |  |  |             'email' => 'unknown@example.com', | 
					
						
							|  |  |  |         ]; | 
					
						
							|  |  |  |         if (auth()->check()) { | 
					
						
							|  |  |  |             $userData['id']    = auth()->user()->id; | 
					
						
							|  |  |  |             $userData['email'] = auth()->user()->email; | 
					
						
							|  |  |  |         } | 
					
						
							| 
									
										
										
										
											2022-03-06 16:03:52 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-06-12 15:41:41 +02:00
										 |  |  |         $headers         = request()->headers->all(); | 
					
						
							| 
									
										
										
										
											2022-03-06 16:03:52 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-06-12 15:41:41 +02:00
										 |  |  |         $data            = [ | 
					
						
							| 
									
										
										
										
											2025-05-04 12:57:14 +02:00
										 |  |  |             'class'        => $e::class, | 
					
						
							| 
									
										
										
										
											2021-04-03 12:25:35 +02:00
										 |  |  |             'errorMessage' => $e->getMessage(), | 
					
						
							| 
									
										
										
										
											2025-05-27 17:02:18 +02:00
										 |  |  |             'time'         => Carbon::now()->format('r'), | 
					
						
							| 
									
										
										
										
											2021-04-03 12:25:35 +02:00
										 |  |  |             'stackTrace'   => $e->getTraceAsString(), | 
					
						
							|  |  |  |             'file'         => $e->getFile(), | 
					
						
							|  |  |  |             'line'         => $e->getLine(), | 
					
						
							|  |  |  |             'code'         => $e->getCode(), | 
					
						
							|  |  |  |             'version'      => config('firefly.version'), | 
					
						
							|  |  |  |             'url'          => request()->fullUrl(), | 
					
						
							|  |  |  |             'userAgent'    => request()->userAgent(), | 
					
						
							|  |  |  |             'json'         => request()->acceptsJson(), | 
					
						
							| 
									
										
										
										
											2022-04-03 12:38:17 +02:00
										 |  |  |             'method'       => request()->method(), | 
					
						
							| 
									
										
										
										
											2022-03-06 16:03:52 +01:00
										 |  |  |             'headers'      => $headers, | 
					
						
							| 
									
										
										
										
											2025-05-27 17:02:18 +02:00
										 |  |  |             'post'         => 'POST' === request()->method() ? json_encode(request()->all()) : '', | 
					
						
							| 
									
										
										
										
											2021-04-03 12:25:35 +02:00
										 |  |  |         ]; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         // create job that will mail.
 | 
					
						
							| 
									
										
										
										
											2025-06-12 15:41:41 +02:00
										 |  |  |         $ipAddress       = request()->ip() ?? '0.0.0.0'; | 
					
						
							|  |  |  |         $job             = new MailError($userData, (string) config('firefly.site_owner'), $ipAddress, $data); | 
					
						
							| 
									
										
										
										
											2021-04-03 12:25:35 +02:00
										 |  |  |         dispatch($job); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         parent::report($e); | 
					
						
							| 
									
										
										
										
											2016-09-16 06:40:45 +02:00
										 |  |  |     } | 
					
						
							| 
									
										
										
										
											2021-04-03 12:32:29 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-05-27 16:57:36 +02:00
										 |  |  |     private function shouldntReportLocal(Throwable $e): bool | 
					
						
							| 
									
										
										
										
											2024-02-22 20:11:09 +01:00
										 |  |  |     { | 
					
						
							|  |  |  |         return null !== Arr::first( | 
					
						
							|  |  |  |             $this->dontReport, | 
					
						
							| 
									
										
										
										
											2025-05-04 13:55:42 +02:00
										 |  |  |             static fn ($type) => $e instanceof $type | 
					
						
							| 
									
										
										
										
											2024-02-22 20:11:09 +01:00
										 |  |  |         ); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-10-02 13:28:56 +02:00
										 |  |  |     /** | 
					
						
							|  |  |  |      * Convert a validation exception into a response. | 
					
						
							|  |  |  |      * | 
					
						
							| 
									
										
										
										
											2023-12-20 19:35:52 +01:00
										 |  |  |      * @param Request $request | 
					
						
							| 
									
										
										
										
											2021-10-02 13:28:56 +02:00
										 |  |  |      */ | 
					
						
							| 
									
										
										
										
											2025-05-27 16:57:36 +02:00
										 |  |  |     #[Override]
 | 
					
						
							| 
									
										
										
										
											2024-01-04 15:42:00 +01:00
										 |  |  |     protected function invalid($request, LaravelValidationException $exception): \Illuminate\Http\Response|JsonResponse|RedirectResponse | 
					
						
							| 
									
										
										
										
											2021-10-02 13:28:56 +02:00
										 |  |  |     { | 
					
						
							|  |  |  |         // protect against open redirect when submitting invalid forms.
 | 
					
						
							| 
									
										
										
										
											2021-10-03 06:05:30 +02:00
										 |  |  |         $previous = app('steam')->getSafePreviousUrl(); | 
					
						
							| 
									
										
										
										
											2021-10-02 13:28:56 +02:00
										 |  |  |         $redirect = $this->getRedirectUrl($exception); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         return redirect($redirect ?? $previous) | 
					
						
							|  |  |  |             ->withInput(Arr::except($request->input(), $this->dontFlash)) | 
					
						
							| 
									
										
										
										
											2024-01-04 15:42:00 +01:00
										 |  |  |             ->withErrors($exception->errors(), $request->input('_error_bag', $exception->errorBag)) | 
					
						
							|  |  |  |         ; | 
					
						
							| 
									
										
										
										
											2023-12-20 19:35:52 +01:00
										 |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-10-02 13:28:56 +02:00
										 |  |  |     /** | 
					
						
							|  |  |  |      * Only return the redirectTo property from the exception if it is a valid URL. Return NULL otherwise. | 
					
						
							|  |  |  |      */ | 
					
						
							|  |  |  |     private function getRedirectUrl(LaravelValidationException $exception): ?string | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |         if (null === $exception->redirectTo) { | 
					
						
							|  |  |  |             return null; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |         $safe         = route('index'); | 
					
						
							|  |  |  |         $previous     = $exception->redirectTo; | 
					
						
							| 
									
										
										
										
											2025-05-27 17:02:18 +02:00
										 |  |  |         $previousHost = parse_url($previous, PHP_URL_HOST); | 
					
						
							|  |  |  |         $safeHost     = parse_url($safe, PHP_URL_HOST); | 
					
						
							| 
									
										
										
										
											2021-10-02 13:28:56 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |         return null !== $previousHost && $previousHost === $safeHost ? $previous : $safe; | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2015-02-06 04:39:52 +01:00
										 |  |  | } |