Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[11.x] Improves errors #51261

Merged
merged 91 commits into from
May 27, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
91 commits
Select commit Hold shift + click to select a range
c31bbd3
Adds initial work
nunomaduro Apr 4, 2024
7263d33
Apply fixes from StyleCI
StyleCIBot Apr 4, 2024
a397624
No need for register anonymous components path
nunomaduro Apr 4, 2024
ccd77d2
Dont map line and file
nunomaduro Apr 4, 2024
b5caa3e
Fixes access to blade exception
nunomaduro Apr 4, 2024
092de50
Apply fixes from StyleCI
StyleCIBot Apr 4, 2024
0e52b0b
Adds context
nunomaduro Apr 4, 2024
c194ed3
Adds body and headers
nunomaduro Apr 5, 2024
390ede3
Adds database queries
nunomaduro Apr 5, 2024
2807ed0
Fixes displaying Laravel Error Exceptions trace
nunomaduro Apr 5, 2024
0de6f64
Improves queries over 100
nunomaduro Apr 5, 2024
5d8a843
Refactors style and scripts
nunomaduro Apr 5, 2024
6ffa8ff
refactors
nunomaduro Apr 5, 2024
34ca579
chore: coding style
nunomaduro Apr 8, 2024
4686a98
Reverts
nunomaduro Apr 24, 2024
85390e8
Reverts
nunomaduro Apr 24, 2024
dae1a6c
Adds work in progress regarding design
nunomaduro Apr 25, 2024
5b0572a
Style changes
nunomaduro Apr 26, 2024
b176f4f
Adds hover
nunomaduro Apr 26, 2024
8651f25
Continues to style things
nunomaduro Apr 26, 2024
5ac2c76
Renders tailwindcss first
nunomaduro Apr 26, 2024
e41b24a
Uses night mode by default
nunomaduro Apr 26, 2024
2e1051e
Ui change
nunomaduro Apr 26, 2024
e43a7cc
Fixes displaying body values
nunomaduro Apr 28, 2024
2a4df72
Improves styling
nunomaduro Apr 29, 2024
5d0dca0
More style changes
nunomaduro Apr 29, 2024
ba053be
Fix rendering within Livewire
nunomaduro Apr 29, 2024
a87f860
Apply fixes from StyleCI
StyleCIBot Apr 29, 2024
b43be30
More styling
nunomaduro Apr 29, 2024
1ad3073
Improves bundling
nunomaduro Apr 29, 2024
72f7933
Uses dark mode by default
nunomaduro Apr 29, 2024
84f7cda
Apply fixes from StyleCI
StyleCIBot Apr 29, 2024
449c08b
Applies styling
nunomaduro Apr 29, 2024
8dee297
Removes pint file
nunomaduro Apr 29, 2024
4d69f8b
Reverts BC
nunomaduro Apr 29, 2024
3d0d0d6
coding style
nunomaduro Apr 29, 2024
c30904a
More styling
nunomaduro Apr 30, 2024
0c890c6
Apply fixes from StyleCI
StyleCIBot Apr 30, 2024
437b517
Adjusts style
nunomaduro Apr 30, 2024
40883b2
Apply fixes from StyleCI
StyleCIBot Apr 30, 2024
f94b363
Fixes style
nunomaduro Apr 30, 2024
0106729
Styles again
nunomaduro Apr 30, 2024
e774fad
Simplifies code
nunomaduro Apr 30, 2024
56ef11f
Adjusts style
nunomaduro Apr 30, 2024
a025b3d
style
nunomaduro Apr 30, 2024
0314ded
More styling
nunomaduro Apr 30, 2024
8009cb1
Inline favicon
nunomaduro Apr 30, 2024
fcf6975
Minor style issues
nunomaduro Apr 30, 2024
6088fa1
coding style
nunomaduro Apr 30, 2024
85e0265
Small changes
nunomaduro Apr 30, 2024
bc41751
Renames
nunomaduro Apr 30, 2024
fce47a5
Removes non used packages
nunomaduro Apr 30, 2024
93d132c
Rebuilds
nunomaduro Apr 30, 2024
198884f
Removes code
nunomaduro Apr 30, 2024
30932a3
Fixes Octane
nunomaduro Apr 30, 2024
bd87aaf
Styles back
nunomaduro Apr 30, 2024
92bd3ee
Improves code
nunomaduro Apr 30, 2024
855094d
Refactor
nunomaduro Apr 30, 2024
3ffc32e
Removes computer
nunomaduro Apr 30, 2024
32e440d
Removes non used bundled package
nunomaduro Apr 30, 2024
c26e6f6
var hint
nunomaduro Apr 30, 2024
f9877a9
Reduces css size
nunomaduro Apr 30, 2024
99effbd
Removes non used method
nunomaduro Apr 30, 2024
3c9c3a5
Apply fixes from StyleCI
StyleCIBot Apr 30, 2024
a209bb5
wording
nunomaduro Apr 30, 2024
1729b66
No need for rescue
nunomaduro Apr 30, 2024
a4257a2
Refactors
nunomaduro May 1, 2024
015186d
Only registers exceptions pages, if needed
nunomaduro May 1, 2024
b1acd72
adds bindings
nunomaduro May 1, 2024
825993b
defaults
nunomaduro May 1, 2024
408a8c9
Reworks icons
nunomaduro May 1, 2024
3b935f1
Revert "Removes computer"
nunomaduro May 1, 2024
4eec204
Adds system mode
nunomaduro May 1, 2024
de630d8
Allows to open on editor
nunomaduro May 1, 2024
c18ef5a
Apply fixes from StyleCI
StyleCIBot May 1, 2024
46d8c72
Adds context about routing
nunomaduro May 1, 2024
9c6ad79
Rebuilds scripts
nunomaduro May 1, 2024
3b5cc9f
Rebuild asset
nunomaduro May 1, 2024
5b9f625
Fixes undefined line
nunomaduro May 1, 2024
9cf2481
wip
nunomaduro May 1, 2024
9aac7b8
fixes
nunomaduro May 1, 2024
eb46fe5
Minor fixes
nunomaduro May 1, 2024
821d599
Styling
nunomaduro May 1, 2024
a564c80
minor
nunomaduro May 1, 2024
c8aa224
wip
nunomaduro May 1, 2024
fa2cb56
Adjusts
nunomaduro May 1, 2024
f0f992f
formatting
taylorotwell May 20, 2024
9f6cae3
formatting
taylorotwell May 20, 2024
130e6eb
Formatting
taylorotwell May 20, 2024
b70e5f8
Fixes method typo
nunomaduro May 27, 2024
acce8a7
Adjusts coding style
nunomaduro May 27, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
7 changes: 6 additions & 1 deletion .styleci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,11 @@ php:
- bad-syntax-strategy.php
js:
finder:
exclude:
- src/Illuminate/Foundation/resources/exceptions/renderer/dist
not-name:
- webpack.mix.js
css: true
css:
finder:
exclude:
- src/Illuminate/Foundation/resources/exceptions/renderer/dist
11 changes: 8 additions & 3 deletions src/Illuminate/Foundation/Exceptions/Handler.php
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
use Illuminate\Database\Eloquent\ModelNotFoundException;
use Illuminate\Database\MultipleRecordsFoundException;
use Illuminate\Database\RecordsNotFoundException;
use Illuminate\Foundation\Exceptions\Renderer\Renderer;
use Illuminate\Http\Exceptions\HttpResponseException;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\RedirectResponse;
Expand Down Expand Up @@ -831,9 +832,13 @@ protected function convertExceptionToResponse(Throwable $e)
protected function renderExceptionContent(Throwable $e)
{
try {
return config('app.debug') && app()->has(ExceptionRenderer::class)
? $this->renderExceptionWithCustomRenderer($e)
: $this->renderExceptionWithSymfony($e, config('app.debug'));
if (config('app.debug')) {
return app()->has(ExceptionRenderer::class)
? $this->renderExceptionWithCustomRenderer($e)
: $this->container->make(Renderer::class)->render(request(), $e);
}

return $this->renderExceptionWithSymfony($e, config('app.debug'));
} catch (Throwable $e) {
return $this->renderExceptionWithSymfony($e, config('app.debug'));
}
Expand Down
220 changes: 220 additions & 0 deletions src/Illuminate/Foundation/Exceptions/Renderer/Exception.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,220 @@
<?php

namespace Illuminate\Foundation\Exceptions\Renderer;

use Composer\Autoload\ClassLoader;
use Illuminate\Foundation\Bootstrap\HandleExceptions;
use Illuminate\Http\Request;
use Symfony\Component\ErrorHandler\Exception\FlattenException;

class Exception
{
/**
* The "flattened" exception instance.
*
* @var \Symfony\Component\ErrorHandler\Exception\FlattenException
*/
protected $exception;

/**
* The current request instance.
*
* @var \Illuminate\Http\Request
*/
protected $request;

/**
* The exception listener instance.
*
* @var \Illuminate\Foundation\Exceptions\Renderer\Listener
*/
protected $listener;

/**
* The application's base path.
*
* @var string
*/
protected $basePath;

/**
* Creates a new exception renderer instance.
*
* @param \Symfony\Component\ErrorHandler\Exception\FlattenException $exception
* @param \Illuminate\Http\Request $request
* @param \Illuminate\Foundation\Exceptions\Renderer\Listener $listener
* @param string $basePath
* @return void
*/
public function __construct(FlattenException $exception, Request $request, Listener $listener, string $basePath)
{
$this->exception = $exception;
$this->request = $request;
$this->listener = $listener;
$this->basePath = $basePath;
}

/**
* Get the exception title.
*
* @return string
*/
public function title()
{
return $this->exception->getStatusText();
}

/**
* Get the exception message.
*
* @return string
*/
public function message()
{
return $this->exception->getMessage();
}

/**
* Get the exception class name.
*
* @return string
*/
public function class()
{
return $this->exception->getClass();
}

/**
* Get the first "non-vendor" frame index.
*
* @return int
*/
public function defaultFrame()
{
$key = array_search(false, array_map(function (Frame $frame) {
return $frame->isFromVendor();
}, $this->frames()->all()));

return $key === false ? 0 : $key;
}

/**
* Get the exception's frames.
*
* @return \Illuminate\Support\Collection<int, Frame>
*/
public function frames()
{
$classMap = once(fn () => array_map(function ($path) {
return (string) realpath($path);
}, array_values(ClassLoader::getRegisteredLoaders())[0]->getClassMap()));

$trace = array_values(array_filter(
$this->exception->getTrace(), fn ($trace) => isset($trace['file']),
));

if (($trace[1]['class'] ?? '') === HandleExceptions::class) {
array_shift($trace);
array_shift($trace);
}

return collect(array_map(
fn (array $trace) => new Frame($this->exception, $classMap, $trace, $this->basePath), $trace,
));
}

/**
* Get the exception's request instance.
*
* @return \Illuminate\Http\Request
*/
public function request()
{
return $this->request;
}

/**
* Get the request's headers.
*
* @return array<string, string>
*/
public function requestHeaders()
{
return array_map(function (array $header) {
return implode(', ', $header);
}, $this->request()->headers->all());
}

/**
* Get the request's body parameters.
*
* @return string|null
*/
public function requestBody()
{
if (empty($payload = $this->request()->all())) {
return null;
}

$json = (string) json_encode($payload, JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE | JSON_PRETTY_PRINT);

return str_replace('\\', '', $json);
}

/**
* Get the application's route context.
*
* @return array<string, string>|null
*/
public function applicationRouteContext()
{
$route = $this->request()->route();

return $route ? array_filter([
'controller' => $route->getActionName(),
'route name' => $route->getName() ?: null,
'middleware' => implode(', ', $route->gatherMiddleware()),
]) : null;
}

/**
* Get the application's route parameters context.
*
* @return array<string, mixed>|null
*/
public function applicationRouteParametersContext()
{
$parameters = $this->request()->route()->parameters();

return $parameters ? json_encode(array_map(
fn ($value) => $value instanceof Model ? $value->withoutRelations() : $value,
$parameters
), JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE | JSON_PRETTY_PRINT) : null;
}

/**
* Get the application's SQL queries.
*
* @return array<int, array{connectionName: string, time: float, sql: string}>
*/
public function applicationQueries()
{
return array_map(function (array $query) {
$sql = $query['sql'];

foreach ($query['bindings'] as $binding) {
$sql = match (gettype($binding)) {
'integer', 'double' => preg_replace('/\?/', $binding, $sql, 1),
'NULL' => preg_replace('/\?/', 'NULL', $sql, 1),
default => preg_replace('/\?/', "'$binding'", $sql, 1),
};
}

return [
'connectionName' => $query['connectionName'],
'time' => $query['time'],
'sql' => $sql,
];
}, $this->listener->queries());
}
}