Handler::renderHttpException()   A
last analyzed

Complexity

Conditions 2
Paths 2

Size

Total Lines 10

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
c 0
b 0
f 0
dl 0
loc 10
rs 9.9332
cc 2
nc 2
nop 1
1
<?php
2
3
declare(strict_types=1);
4
5
namespace Cortex\Foundation\Exceptions;
6
7
use Exception;
8
use Illuminate\Support\Facades\Route;
9
use Illuminate\Auth\AuthenticationException;
10
use Illuminate\Session\TokenMismatchException;
11
use Illuminate\Validation\ValidationException;
12
use Illuminate\Auth\Access\AuthorizationException;
13
use Illuminate\Database\Eloquent\ModelNotFoundException;
14
use Illuminate\Foundation\Exceptions\Handler as ExceptionHandler;
15
use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
16
use Symfony\Component\HttpKernel\Exception\HttpExceptionInterface;
17
use Watson\Validating\ValidationException as WatsonValidationException;
18
19
class Handler extends ExceptionHandler
20
{
21
    /**
22
     * Report or log an exception.
23
     *
24
     * This is a great spot to send exceptions to Sentry, Bugsnag, etc.
25
     *
26
     * @param \Exception $exception
27
     *
28
     * @throws \Exception
29
     *
30
     * @return void
31
     */
32
    public function report(Exception $exception): void
33
    {
34
        parent::report($exception);
35
    }
36
37
    /**
38
     * Render an exception into an HTTP response.
39
     *
40
     * @param \Illuminate\Http\Request $request
41
     * @param \Exception               $exception
42
     *
43
     * @return \Illuminate\Http\Response|\Symfony\Component\HttpFoundation\Response
44
     */
45
    public function render($request, Exception $exception)
46
    {
47
        $accessarea = str_before(Route::currentRouteName(), '.');
0 ignored issues
show
Deprecated Code introduced by
The function str_before() has been deprecated with message: Str::before() should be used directly instead. Will be removed in Laravel 6.0.

This function has been deprecated. The supplier of the file has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the function will be removed from the class and what other function to use instead.

Loading history...
48
49
        if ($exception instanceof TokenMismatchException) {
50
            return intend([
51
                'back' => true,
52
                'with' => ['warning' => trans('cortex/foundation::messages.token_mismatch')],
53
            ]);
54
        } elseif ($exception instanceof WatsonValidationException) {
55
            return intend([
56
                'back' => true,
57
                'withInput' => $request->all(),
58
                'withErrors' => $exception->errors(),
59
            ]);
60
        } elseif ($exception instanceof ValidationException) {
61
            return intend([
62
                'back' => true,
63
                'withInput' => $request->all(),
64
                'withErrors' => $exception->errors(),
65
            ]);
66
        } elseif ($exception instanceof GenericException) {
67
            return intend([
68
                'url' => $exception->getRedirection() ?? route("{$accessarea}.home"),
69
                'withInput' => $exception->getInputs() ?? $request->all(),
70
                'with' => ['warning' => $exception->getMessage()],
71
            ]);
72
        } elseif ($exception instanceof AuthorizationException) {
73
            return intend([
74
                'url' => in_array($accessarea, ['tenantarea', 'managerarea']) ? route('tenantarea.home') : route('frontarea.home'),
75
                'with' => ['warning' => $exception->getMessage()],
76
            ]);
77
        } elseif ($exception instanceof NotFoundHttpException) {
78
            // Catch localized routes with missing {locale}
79
            // and redirect them to the correct localized version
80
            if (config('cortex.foundation.route.locale_redirect')) {
81
                $originalUrl = $request->url();
82
83
                try {
84
                    $localizedUrl = app('laravellocalization')->getLocalizedURL(null, $originalUrl);
85
86
                    // Will return `NotFoundHttpException` exception if no match found!
87
                    app('router')->getRoutes()->match(request()->create($localizedUrl));
88
89
                    return intend([
90
                        'url' => $originalUrl !== $localizedUrl ? $localizedUrl : route("{$accessarea}.home"),
91
                        'with' => ['warning' => $exception->getMessage()],
92
                    ]);
93
                } catch (Exception $exception) {
0 ignored issues
show
Coding Style Comprehensibility introduced by
Consider adding a comment why this CATCH block is empty.
Loading history...
94
                }
95
            }
96
97
            return $this->prepareResponse($request, $exception);
98
        } elseif ($exception instanceof ModelNotFoundException) {
99
            $model = $exception->getModel();
100
            $single = mb_strtolower(mb_substr($model, mb_strrpos($model, '\\') + 1));
101
            $plural = str_plural($single);
0 ignored issues
show
Deprecated Code introduced by
The function str_plural() has been deprecated with message: Str::plural() should be used directly instead. Will be removed in Laravel 6.0.

This function has been deprecated. The supplier of the file has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the function will be removed from the class and what other function to use instead.

Loading history...
102
103
            return intend([
104
                'url' => $model ? route("{$accessarea}.{$plural}.index") : route("{$accessarea}.home"),
105
                'with' => ['warning' => trans('cortex/foundation::messages.resource_not_found', ['resource' => $single, 'identifier' => $request->route($single)])],
106
            ]);
107
        }
108
109
        return parent::render($request, $exception);
110
    }
111
112
    /**
113
     * Render the given HttpException.
114
     *
115
     * @param \Symfony\Component\HttpKernel\Exception\HttpExceptionInterface $e
0 ignored issues
show
Bug introduced by
There is no parameter named $e. Was it maybe removed?

This check looks for PHPDoc comments describing methods or function parameters that do not exist on the corresponding method or function.

Consider the following example. The parameter $italy is not defined by the method finale(...).

/**
 * @param array $germany
 * @param array $island
 * @param array $italy
 */
function finale($germany, $island) {
    return "2:1";
}

The most likely cause is that the parameter was removed, but the annotation was not.

Loading history...
116
     *
117
     * @return \Symfony\Component\HttpFoundation\Response
118
     */
119
    protected function renderHttpException(HttpExceptionInterface $exception)
120
    {
121
        $status = $exception->getStatusCode();
122
123
        if (view()->exists("cortex/foundation::common.errors.{$status}")) {
0 ignored issues
show
Bug introduced by
The method exists does only exist in Illuminate\Contracts\View\Factory, but not in Illuminate\View\View.

It seems like the method you are trying to call exists only in some of the possible types.

Let’s take a look at an example:

class A
{
    public function foo() { }
}

class B extends A
{
    public function bar() { }
}

/**
 * @param A|B $x
 */
function someFunction($x)
{
    $x->foo(); // This call is fine as the method exists in A and B.
    $x->bar(); // This method only exists in B and might cause an error.
}

Available Fixes

  1. Add an additional type-check:

    /**
     * @param A|B $x
     */
    function someFunction($x)
    {
        $x->foo();
    
        if ($x instanceof B) {
            $x->bar();
        }
    }
    
  2. Only allow a single type to be passed if the variable comes from a parameter:

    function someFunction(B $x) { /** ... */ }
    
Loading history...
124
            return response()->view("cortex/foundation::common.errors.{$status}", ['exception' => $exception], $status, $exception->getHeaders());
0 ignored issues
show
Bug introduced by
The method view does only exist in Illuminate\Contracts\Routing\ResponseFactory, but not in Illuminate\Http\Response.

It seems like the method you are trying to call exists only in some of the possible types.

Let’s take a look at an example:

class A
{
    public function foo() { }
}

class B extends A
{
    public function bar() { }
}

/**
 * @param A|B $x
 */
function someFunction($x)
{
    $x->foo(); // This call is fine as the method exists in A and B.
    $x->bar(); // This method only exists in B and might cause an error.
}

Available Fixes

  1. Add an additional type-check:

    /**
     * @param A|B $x
     */
    function someFunction($x)
    {
        $x->foo();
    
        if ($x instanceof B) {
            $x->bar();
        }
    }
    
  2. Only allow a single type to be passed if the variable comes from a parameter:

    function someFunction(B $x) { /** ... */ }
    
Loading history...
125
        }
126
127
        return parent::renderHttpException($exception);
128
    }
129
130
    /**
131
     * Convert an authentication exception into an unauthenticated response.
132
     *
133
     * @param \Illuminate\Http\Request                 $request
134
     * @param \Illuminate\Auth\AuthenticationException $exception
135
     *
136
     * @return \Illuminate\Http\Response
0 ignored issues
show
Documentation introduced by
Should the return type not be \Illuminate\Http\JsonRes...e\Http\RedirectResponse?

This check compares the return type specified in the @return annotation of a function or method doc comment with the types returned by the function and raises an issue if they mismatch.

Loading history...
137
     */
138
    protected function unauthenticated($request, AuthenticationException $exception)
139
    {
140
        return intend([
141
            'url' => route($request->route('accessarea').'.login'),
142
            'with' => ['warning' => trans('cortex/foundation::messages.session_required')],
143
        ]);
144
    }
145
}
146