2 declare(strict_types = 1);
30 set_exception_handler([$this,
'handleException']);
50 <meta charset=
"UTF-8" />
52 <meta name=
"robots" content=
"noindex,nofollow" />
69 $filePathAndName = $exception->getFile();
70 $exceptionCodeNumber = $exception->getCode() > 0 ?
'#' . $exception->getCode() .
': ' :
'';
72 echo LF .
'Uncaught TYPO3 Exception ' . $exceptionCodeNumber . $exception->getMessage() . LF;
73 echo
'thrown in file ' . $filePathAndName . LF;
74 echo
'in line ' . $exception->getLine() . LF . LF;
91 $count = count($throwables);
92 foreach ($throwables as $position => $e) {
97 if ($throwable->getCode() > 0) {
98 $documentationLink = TYPO3_URL_EXCEPTION .
'debug/' . $throwable->getCode();
99 $exceptionInfo = <<<INFO
100 <div
class=
"container">
101 <div
class=
"callout">
102 <h4
class=
"callout-title">Get help in the
TYPO3 Documentation</h4>
103 <div
class=
"callout-body">
105 If you need help solving
this exception, you can have a look at the
TYPO3 Documentation.
106 There you can find solutions provided by the
TYPO3 community.
107 Once you have found a solution to the problem, help others by contributing to the
111 <a href=
"$documentationLink" target=
"_blank" rel=
"noopener noreferrer">Find a solution
for this exception in the
TYPO3 Documentation.</a>
122 <div
class=
"exception-page">
123 <div
class=
"exception-summary">
124 <div
class=
"container">
125 <div
class=
"exception-message-wrapper">
126 <div
class=
"exception-illustration hidden-xs-down">$typo3Logo</div>
127 <h1
class=
"exception-message break-long-words">Whoops, looks like something went wrong.</h1>
134 <div
class=
"container">
151 $exceptionTitle = get_class($throwable);
152 $exceptionCode = $throwable->getCode() ?
'#' . $throwable->getCode() .
' ' :
'';
153 $exceptionMessage = $this->
escapeHtml($throwable->getMessage());
157 $trace = $throwable->getTrace();
158 array_unshift($trace, [
159 'file' => $throwable->getFile(),
160 'line' => $throwable->getLine(),
168 <div
class=
"trace-head">
169 <h3
class=
"trace-class">
170 <span
class=
"text-muted">({$index}/{$total})</span>
171 <span
class=
"exception-title">{$exceptionCode}{$exceptionTitle}</span>
173 <p
class=
"trace-message break-long-words">{$exceptionMessage}</p>
175 <div
class=
"trace-body">
191 -webkit-text-size-adjust: 100%;
192 -ms-text-size-adjust: 100%;
193 -ms-overflow-style: scrollbar;
194 -webkit-tap-highlight-color: transparent;
202 background-color: #eaeaea;
204 font-family: -apple-system,BlinkMacSystemFont,
"Segoe UI",Roboto,
"Helvetica Neue",Arial,sans-serif,
"Apple Color Emoji",
"Segoe UI Emoji",
"Segoe UI Symbol",
"Noto Color Emoji";
214 .panel-collapse .exception-page {
220 text-decoration: underline;
223 .exception-page a:hover {
224 text-decoration: none;
227 .exception-page abbr[title] {
230 text-decoration: none;
233 .exception-page code,
236 .exception-page samp {
237 font-family: SFMono-Regular,Menlo,Monaco,Consolas,
"Liberation Mono",
"Courier New",monospace;
241 .exception-page pre {
242 background-color: #ffffff;
244 border: 1px solid rgba(0,0,0,0.125);
247 .exception-page pre span {
252 .exception-page pre span:before {
253 display:
inline-block;
254 content: attr(data-line);
255 border-right: 1px solid #b9b9b9;
257 padding-right: 0.5em;
258 background-color: #f4f4f4;
264 .exception-page pre span.highlight {
265 background-color: #cce5ff;
268 .exception-page .break-
long-words {
269 -ms-word-
break:
break-all;
270 word-
break:
break-all;
271 word-
break:
break-word;
272 -webkit-hyphens:
auto;
277 .exception-page .callout {
279 background-color: #fff;
281 box-shadow: 0 2px 1px rgba(0,0,0,.15);
282 border-left: 3px solid #8c8c8c;
285 .exception-page .callout-title {
289 .exception-page .callout-body p:last-child {
293 .exception-page .container {
299 .panel-collapse .exception-page .container {
303 .exception-page .exception-illustration {
310 .exception-page .exception-illustration svg {
314 .exception-page .exception-illustration svg path {
318 .exception-page .exception-summary {
325 .exception-page .exception-summary h1 {
329 .exception-page .text-muted {
333 .exception-page .trace {
334 background-color: #fff;
336 box-shadow: 0 2px 1px rgba(0,0,0,.15);
339 .exception-page .trace-arguments {
343 .exception-page .trace-body {
346 .exception-page .trace-call {
350 .exception-page .trace-
class {
354 .exception-page .trace-file pre {
359 .exception-page .trace-head {
361 background-color: #f8d7da;
365 .exception-page .trace-file-path {
366 word-
break:
break-all;
369 .exception-page .trace-message {
373 .exception-page .trace-step {
375 border-bottom: 1px solid #b9b9b9;
378 .exception-page .trace-step > *:first-child {
382 .exception-page .trace-step > *:last-child {
386 .exception-page .trace-step:nth-child(even)
388 background-color: #fafafa;
391 .exception-page .trace-step:last-child {
407 foreach ($trace as $index => $step) {
408 $content .=
'<div class="trace-step">';
411 if (isset($step[
'function'])) {
412 $content .=
'<div class="trace-call">' . sprintf(
413 'at <span class="trace-class">%s</span><span class="trace-type">%s</span><span class="trace-method">%s</span>(<span class="trace-arguments">%s</span>)',
414 $step[
'class'] ??
'',
421 if (isset($step[
'file']) && isset($step[
'line'])) {
425 $content .=
'</div>';
440 $showLinesAround = 4;
442 $content =
'<div class="trace-file">';
443 $content .=
'<div class="trace-file-head">' . $this->
formatPath($filePathAndName, $lineNumber) .
'</div>';
445 if (@file_exists($filePathAndName)) {
446 $phpFile = @file($filePathAndName);
447 if (is_array($phpFile)) {
448 $startLine = $lineNumber > $showLinesAround ? $lineNumber - $showLinesAround : 1;
449 $phpFileCount = count($phpFile);
450 $endLine = $lineNumber < $phpFileCount - $showLinesAround ? $lineNumber + $showLinesAround + 1 : $phpFileCount + 1;
451 if ($endLine > $startLine) {
452 $content .=
'<div class="trace-file-content">';
455 for ($line = $startLine; $line < $endLine; $line++) {
456 $codeLine = str_replace(TAB,
' ', $phpFile[$line - 1]);
458 if ($line === $lineNumber) {
459 $spanClass =
'highlight';
462 $content .=
'<span class="' . $spanClass .
'" data-line="' . $line .
'">' . $this->
escapeHtml($codeLine) .
'</span>';
465 $content .=
'</pre>';
466 $content .=
'</div>';
471 $content .=
'</div>';
486 '<span class="block trace-file-path">in <strong>%s</strong>%s</span>',
488 0 < $line ?
' line ' . $line :
''
501 foreach (
$args as $key => $item) {
502 if (
'object' === $item[0]) {
503 $formattedValue = sprintf(
'<em>object</em>(%s)', $item[1]);
504 } elseif (
'array' === $item[0]) {
505 $formattedValue = sprintf(
'<em>array</em>(%s)', is_array($item[1]) ? $this->
formatArgs($item[1]) : $item[1]);
506 } elseif (
'null' === $item[0]) {
507 $formattedValue =
'<em>null</em>';
508 } elseif (
'boolean' === $item[0]) {
509 $formattedValue =
'<em>' . strtolower(var_export($item[1],
true)) .
'</em>';
510 } elseif (
'resource' === $item[0]) {
511 $formattedValue =
'<em>resource</em>';
513 $formattedValue = str_replace(
"\n",
'', $this->
escapeHtml(var_export($item[1],
true)));
516 $result[] = \is_int($key) ? $formattedValue : sprintf(
"'%s' => %s", $this->
escapeHtml($key), $formattedValue);
519 return implode(
', ', $result);
525 foreach (
$args as $key => $value) {
526 if (++$count > 1e4) {
527 return [
'array',
'*SKIPPED over 10000 entries*'];
529 if ($value instanceof \__PHP_Incomplete_Class) {
532 } elseif (is_object($value)) {
533 $result[$key] = [
'object', get_class($value)];
534 } elseif (is_array($value)) {
536 $result[$key] = [
'array',
'*DEEP NESTED ARRAY*'];
538 $result[$key] = [
'array', $this->
flattenArgs($value, $level + 1, $count)];
540 } elseif (
null === $value) {
541 $result[$key] = [
'null',
null];
542 } elseif (is_bool($value)) {
543 $result[$key] = [
'boolean', $value];
544 } elseif (is_int($value)) {
545 $result[$key] = [
'integer', $value];
546 } elseif (is_float($value)) {
547 $result[$key] = [
'float', $value];
548 } elseif (is_resource($value)) {
549 $result[$key] = [
'resource', get_resource_type($value)];
551 $result[$key] = [
'string', (string)$value];
560 $array = new \ArrayObject($value);
562 return $array[
'__PHP_Incomplete_Class_Name'];
567 return htmlspecialchars($str, ENT_COMPAT | ENT_SUBSTITUTE);
573 <svg xmlns=
"http://www.w3.org/2000/svg" viewBox=
"0 0 16 16"><path d=
"M11.1 10.3c-.2 0-.3.1-.5.1C9 10.4 6.8 5 6.8 3.2c0-.7.2-.9.4-1.1-2 .2-4.2.9-4.9 1.8-.2.2-.3.6-.3 1 0 2.8 3 9.2 5.1 9.2 1 0 2.6-1.6 4-3.8m-1-8.4c1.9 0 3.9.3 3.9 1.4 0 2.2-1.4 4.9-2.1 4.9C10.6 8.3 9 4.7 9 2.9c0-.8.3-1 1.1-1"></path></svg>
581 while ($throwable = $throwable->getPrevious()) {