Added custom whoops-based debug view

Provides a simple bookstack focused view that does not rely on JavaScript.
Contains links to BookStack specific resources in addition to commonly
desired debug details.
This commit is contained in:
Dan Brown 2021-10-14 15:33:08 +01:00
parent 69301f7575
commit 9b8bb49a33
No known key found for this signature in database
GPG key ID: 46D9F943C24A2EF9
5 changed files with 212 additions and 279 deletions

View file

@ -0,0 +1,51 @@
<?php
namespace BookStack\Exceptions;
use Whoops\Handler\Handler;
class WhoopsBookStackPrettyHandler extends Handler
{
/**
* @return int|null A handler may return nothing, or a Handler::HANDLE_* constant
*/
public function handle()
{
// TODO - Assistance View
// Docs links
// Discord Links
// Github Issue Links (With pre-filled search?)
$exception = $this->getException();
echo view('errors.debug', [
'error' => $exception->getMessage(),
'errorClass' => get_class($exception),
'trace' => $exception->getTraceAsString(),
'environment' => $this->getEnvironment(),
])->render();
return Handler::QUIT;
}
protected function safeReturn(callable $callback, $default = null) {
try {
return $callback();
} catch (\Exception $e) {
return $default;
}
}
protected function getEnvironment(): array
{
return [
'PHP Version' => phpversion(),
'BookStack Version' => $this->safeReturn(function() {
$versionFile = base_path('version');
return trim(file_get_contents($versionFile));
}, 'unknown'),
'Theme Configured' => $this->safeReturn(function() {
return config('view.theme');
}) ?? 'None',
];
}
}

View file

@ -9,6 +9,7 @@ use BookStack\Entities\Models\Book;
use BookStack\Entities\Models\Bookshelf;
use BookStack\Entities\Models\Chapter;
use BookStack\Entities\Models\Page;
use BookStack\Exceptions\WhoopsBookStackPrettyHandler;
use BookStack\Settings\Setting;
use BookStack\Settings\SettingService;
use BookStack\Util\CspService;
@ -20,6 +21,7 @@ use Illuminate\Support\Facades\URL;
use Illuminate\Support\Facades\View;
use Illuminate\Support\ServiceProvider;
use Laravel\Socialite\Contracts\Factory as SocialiteFactory;
use Whoops\Handler\HandlerInterface;
class AppServiceProvider extends ServiceProvider
{
@ -65,6 +67,10 @@ class AppServiceProvider extends ServiceProvider
*/
public function register()
{
$this->app->bind(HandlerInterface::class, function($app) {
return $app->make(WhoopsBookStackPrettyHandler::class);
});
$this->app->singleton(SettingService::class, function ($app) {
return new SettingService($app->make(Setting::class), $app->make(Repository::class));
});

View file

@ -17,8 +17,8 @@
"barryvdh/laravel-dompdf": "^0.9.0",
"barryvdh/laravel-snappy": "^0.4.8",
"doctrine/dbal": "^2.12.1",
"facade/ignition": "^1.16.4",
"fideloper/proxy": "^4.4.1",
"filp/whoops": "^2.14",
"intervention/image": "^2.5.1",
"laravel/framework": "^6.20.33",
"laravel/socialite": "^5.1",

286
composer.lock generated
View file

@ -4,7 +4,7 @@
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
"This file is @generated automatically"
],
"content-hash": "10825887b8f66d1d412b92bcc0ca864f",
"content-hash": "d59a665fcd692fc0ddf12e7e4f96d4f1",
"packages": [
{
"name": "aws/aws-crt-php",
@ -1102,200 +1102,6 @@
],
"time": "2020-12-29T14:50:06+00:00"
},
{
"name": "facade/flare-client-php",
"version": "1.9.1",
"source": {
"type": "git",
"url": "https://github.com/facade/flare-client-php.git",
"reference": "b2adf1512755637d0cef4f7d1b54301325ac78ed"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/facade/flare-client-php/zipball/b2adf1512755637d0cef4f7d1b54301325ac78ed",
"reference": "b2adf1512755637d0cef4f7d1b54301325ac78ed",
"shasum": ""
},
"require": {
"facade/ignition-contracts": "~1.0",
"illuminate/pipeline": "^5.5|^6.0|^7.0|^8.0",
"php": "^7.1|^8.0",
"symfony/http-foundation": "^3.3|^4.1|^5.0",
"symfony/mime": "^3.4|^4.0|^5.1",
"symfony/var-dumper": "^3.4|^4.0|^5.0"
},
"require-dev": {
"friendsofphp/php-cs-fixer": "^2.14",
"phpunit/phpunit": "^7.5.16",
"spatie/phpunit-snapshot-assertions": "^2.0"
},
"type": "library",
"extra": {
"branch-alias": {
"dev-master": "1.0-dev"
}
},
"autoload": {
"psr-4": {
"Facade\\FlareClient\\": "src"
},
"files": [
"src/helpers.php"
]
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"description": "Send PHP errors to Flare",
"homepage": "https://github.com/facade/flare-client-php",
"keywords": [
"exception",
"facade",
"flare",
"reporting"
],
"support": {
"issues": "https://github.com/facade/flare-client-php/issues",
"source": "https://github.com/facade/flare-client-php/tree/1.9.1"
},
"funding": [
{
"url": "https://github.com/spatie",
"type": "github"
}
],
"time": "2021-09-13T12:16:46+00:00"
},
{
"name": "facade/ignition",
"version": "1.18.0",
"source": {
"type": "git",
"url": "https://github.com/facade/ignition.git",
"reference": "fca0cbe5f900f94773d821b481c16d4ea3503491"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/facade/ignition/zipball/fca0cbe5f900f94773d821b481c16d4ea3503491",
"reference": "fca0cbe5f900f94773d821b481c16d4ea3503491",
"shasum": ""
},
"require": {
"ext-json": "*",
"ext-mbstring": "*",
"facade/flare-client-php": "^1.3",
"facade/ignition-contracts": "^1.0",
"filp/whoops": "^2.4",
"illuminate/support": "~5.5.0 || ~5.6.0 || ~5.7.0 || ~5.8.0 || ^6.0",
"monolog/monolog": "^1.12 || ^2.0",
"php": "^7.1|^8.0",
"scrivo/highlight.php": "^9.15",
"symfony/console": "^3.4 || ^4.0",
"symfony/var-dumper": "^3.4 || ^4.0"
},
"require-dev": {
"mockery/mockery": "~1.3.3|^1.4.2",
"orchestra/testbench": "^3.5 || ^3.6 || ^3.7 || ^3.8 || ^4.0"
},
"suggest": {
"laravel/telescope": "^2.0"
},
"type": "library",
"extra": {
"branch-alias": {
"dev-master": "1.x-dev"
},
"laravel": {
"providers": [
"Facade\\Ignition\\IgnitionServiceProvider"
],
"aliases": {
"Flare": "Facade\\Ignition\\Facades\\Flare"
}
}
},
"autoload": {
"psr-4": {
"Facade\\Ignition\\": "src"
},
"files": [
"src/helpers.php"
]
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"description": "A beautiful error page for Laravel applications.",
"homepage": "https://github.com/facade/ignition",
"keywords": [
"error",
"flare",
"laravel",
"page"
],
"support": {
"docs": "https://flareapp.io/docs/ignition-for-laravel/introduction",
"forum": "https://twitter.com/flareappio",
"issues": "https://github.com/facade/ignition/issues",
"source": "https://github.com/facade/ignition"
},
"time": "2021-08-02T07:45:03+00:00"
},
{
"name": "facade/ignition-contracts",
"version": "1.0.2",
"source": {
"type": "git",
"url": "https://github.com/facade/ignition-contracts.git",
"reference": "3c921a1cdba35b68a7f0ccffc6dffc1995b18267"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/facade/ignition-contracts/zipball/3c921a1cdba35b68a7f0ccffc6dffc1995b18267",
"reference": "3c921a1cdba35b68a7f0ccffc6dffc1995b18267",
"shasum": ""
},
"require": {
"php": "^7.3|^8.0"
},
"require-dev": {
"friendsofphp/php-cs-fixer": "^v2.15.8",
"phpunit/phpunit": "^9.3.11",
"vimeo/psalm": "^3.17.1"
},
"type": "library",
"autoload": {
"psr-4": {
"Facade\\IgnitionContracts\\": "src"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Freek Van der Herten",
"email": "freek@spatie.be",
"homepage": "https://flareapp.io",
"role": "Developer"
}
],
"description": "Solution contracts for Ignition",
"homepage": "https://github.com/facade/ignition-contracts",
"keywords": [
"contracts",
"flare",
"ignition"
],
"support": {
"issues": "https://github.com/facade/ignition-contracts/issues",
"source": "https://github.com/facade/ignition-contracts/tree/1.0.2"
},
"time": "2020-10-16T08:27:54+00:00"
},
{
"name": "fideloper/proxy",
"version": "4.4.1",
@ -1356,21 +1162,21 @@
},
{
"name": "filp/whoops",
"version": "2.14.1",
"version": "2.14.4",
"source": {
"type": "git",
"url": "https://github.com/filp/whoops.git",
"reference": "15ead64e9828f0fc90932114429c4f7923570cb1"
"reference": "f056f1fe935d9ed86e698905a957334029899895"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/filp/whoops/zipball/15ead64e9828f0fc90932114429c4f7923570cb1",
"reference": "15ead64e9828f0fc90932114429c4f7923570cb1",
"url": "https://api.github.com/repos/filp/whoops/zipball/f056f1fe935d9ed86e698905a957334029899895",
"reference": "f056f1fe935d9ed86e698905a957334029899895",
"shasum": ""
},
"require": {
"php": "^5.5.9 || ^7.0 || ^8.0",
"psr/log": "^1.0.1"
"psr/log": "^1.0.1 || ^2.0 || ^3.0"
},
"require-dev": {
"mockery/mockery": "^0.9 || ^1.0",
@ -1415,7 +1221,7 @@
],
"support": {
"issues": "https://github.com/filp/whoops/issues",
"source": "https://github.com/filp/whoops/tree/2.14.1"
"source": "https://github.com/filp/whoops/tree/2.14.4"
},
"funding": [
{
@ -1423,7 +1229,7 @@
"type": "github"
}
],
"time": "2021-08-29T12:00:00+00:00"
"time": "2021-10-03T12:00:00+00:00"
},
{
"name": "guzzlehttp/guzzle",
@ -3939,82 +3745,6 @@
},
"time": "2020-06-01T09:10:00+00:00"
},
{
"name": "scrivo/highlight.php",
"version": "v9.18.1.7",
"source": {
"type": "git",
"url": "https://github.com/scrivo/highlight.php.git",
"reference": "05996fcc61e97978d76ca7d1ac14b65e7cd26f91"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/scrivo/highlight.php/zipball/05996fcc61e97978d76ca7d1ac14b65e7cd26f91",
"reference": "05996fcc61e97978d76ca7d1ac14b65e7cd26f91",
"shasum": ""
},
"require": {
"ext-json": "*",
"ext-mbstring": "*",
"php": ">=5.4"
},
"require-dev": {
"phpunit/phpunit": "^4.8|^5.7",
"sabberworm/php-css-parser": "^8.3",
"symfony/finder": "^2.8|^3.4",
"symfony/var-dumper": "^2.8|^3.4"
},
"type": "library",
"autoload": {
"psr-0": {
"Highlight\\": "",
"HighlightUtilities\\": ""
},
"files": [
"HighlightUtilities/functions.php"
]
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"BSD-3-Clause"
],
"authors": [
{
"name": "Geert Bergman",
"homepage": "http://www.scrivo.org/",
"role": "Project Author"
},
{
"name": "Vladimir Jimenez",
"homepage": "https://allejo.io",
"role": "Maintainer"
},
{
"name": "Martin Folkers",
"homepage": "https://twobrain.io",
"role": "Contributor"
}
],
"description": "Server side syntax highlighter that supports 185 languages. It's a PHP port of highlight.js",
"keywords": [
"code",
"highlight",
"highlight.js",
"highlight.php",
"syntax"
],
"support": {
"issues": "https://github.com/scrivo/highlight.php/issues",
"source": "https://github.com/scrivo/highlight.php"
},
"funding": [
{
"url": "https://github.com/allejo",
"type": "github"
}
],
"time": "2021-07-09T00:30:39+00:00"
},
{
"name": "socialiteproviders/discord",
"version": "4.1.1",

View file

@ -0,0 +1,146 @@
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport"
content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
<title>Error: {{ $error }}</title>
<style>
html, body {
background-color: #F2F2F2;
font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", "Oxygen", "Ubuntu", "Roboto", "Cantarell", "Fira Sans", "Droid Sans", "Helvetica Neue", sans-serif;
}
html {
padding: 0;
}
body {
margin: 0;
border-top: 6px solid #206ea7;
}
h1 {
margin-top: 0;
}
h2 {
color: #666;
font-size: 1rem;
margin-bottom: 0;
}
.container {
max-width: 800px;
margin: 1rem auto;
}
.panel {
background-color: #FFF;
border-radius: 3px;
box-shadow: 0 1px 6px -1px rgba(0, 0, 0, 0.1);
padding: 1rem 2rem;
margin: 2rem 1rem;
}
.panel-title {
font-weight: bold;
font-size: 1rem;
color: #FFF;
margin-top: 0;
margin-bottom: 0;
background-color: #206ea7;
padding: 0.25rem .5rem;
display: inline-block;
border-radius: 3px;
}
pre {
overflow-x: scroll;
background-color: #EEE;
border: 1px solid #DDD;
padding: .25rem;
border-radius: 3px;
}
a {
color: #206ea7;
text-decoration: none;
}
a:hover, a:focus {
text-decoration: underline;
color: #105282;
}
ul {
margin-left: 0;
padding-left: 1rem;
}
li {
margin-bottom: .4rem;
}
.notice {
margin-top: 2rem;
padding: 0 2rem;
font-weight: bold;
color: #666;
}
</style>
</head>
<body>
<div class="container">
<p class="notice">
WARNING: Application is in debug mode. This mode has the potential to leak confidential
information and therefore should not be used in production or publicly
accessible environments.
</p>
<div class="panel">
<h4 class="panel-title">Error</h4>
<h2>{{ $errorClass }}</h2>
<h1>{{ $error }}</h1>
</div>
<div class="panel">
<h4 class="panel-title">Help Resources</h4>
<ul>
<li>
<a href="https://www.bookstackapp.com/docs/admin/debugging/" target="_blank">Review BookStack debugging documentation &raquo;</a>
</li>
<li>
<a href="https://github.com/BookStackApp/BookStack/releases" target="_blank">Ensure your instance is up-to-date &raquo;</a>
</li>
<li>
<a href="https://github.com/BookStackApp/BookStack/issues?q=is%3Aissue+{{ urlencode($error) }}" target="_blank">Search for the issue on GitHub &raquo;</a>
</li>
<li>
<a href="https://discord.gg/ztkBqR2" target="_blank">Ask for help via Discord &raquo;</a>
</li>
<li>
<a href="https://duckduckgo.com/?q={{urlencode("BookStack {$error}")}}" target="_blank">Search the error message &raquo;</a>
</li>
</ul>
</div>
<div class="panel">
<h4 class="panel-title">Environment</h4>
<ul>
@foreach($environment as $label => $text)
<li><strong>{{ $label }}:</strong> {{ $text }}</li>
@endforeach
</ul>
</div>
<div class="panel">
<h4 class="panel-title">Stack Trace</h4>
<pre>{{ $trace }}</pre>
</div>
</div>
</body>
</html>