diff --git a/src/Phaseolies/Error/WebErrorRenderer.php b/src/Phaseolies/Error/WebErrorRenderer.php index 7f094b4..a1583aa 100644 --- a/src/Phaseolies/Error/WebErrorRenderer.php +++ b/src/Phaseolies/Error/WebErrorRenderer.php @@ -9,6 +9,8 @@ use Phaseolies\Http\Controllers\Controller; use Throwable; +use function Tests\Unit\Application\config; + class WebErrorRenderer { /** @@ -47,8 +49,6 @@ public function renderDebug(Throwable $exception): string 'email' => $user->email ?? 'N/A', ] : null; - date_default_timezone_set(config('app.timezone')); - $mdReport = new ExceptionMarkdownReport($exception); // setup the controller to point out to different views location @@ -68,6 +68,7 @@ public function renderDebug(Throwable $exception): string 'php_version' => PHP_VERSION, 'doppar_version' => Application::VERSION, 'request_method' => request()->getMethod(), + 'request_body' => request()->all(), 'request_url' => trim(request()->fullUrl(), '/'), 'timestamp' => now()->toDayDateTimeString(), 'server_software' => $_SERVER['SERVER_SOFTWARE'] ?? 'Unknown', @@ -79,6 +80,10 @@ public function renderDebug(Throwable $exception): string 'exception_class' => class_basename($exception), 'status_code' => $exception->getCode() ?: 500, 'md_content' => $mdReport->generate(), + 'current_middleware' => \Phaseolies\Support\Facades\Route::getCurrentMiddlewareNames(), + 'current_route_name' => \Phaseolies\Support\Facades\Route::currentRouteName(), + 'current_route_action' => \Phaseolies\Support\Facades\Route::currentRouteAction(), + 'current_route_params' => request()->getRouteParams() ]); } diff --git a/src/Phaseolies/Error/views/template-headers.odo.php b/src/Phaseolies/Error/views/template-headers.odo.php index a0bb61b..85432da 100644 --- a/src/Phaseolies/Error/views/template-headers.odo.php +++ b/src/Phaseolies/Error/views/template-headers.odo.php @@ -1,38 +1,25 @@ -
-
- - - - -
-
\ No newline at end of file + +
+
+ #foreach ($headers as $header_name => $header_value) +
+ [[ $header_name ]] +
+ [[ $header_value ]] +
+ #endforeach +
+
\ No newline at end of file diff --git a/src/Phaseolies/Error/views/template.odo.php b/src/Phaseolies/Error/views/template.odo.php index bd10d1b..a761081 100644 --- a/src/Phaseolies/Error/views/template.odo.php +++ b/src/Phaseolies/Error/views/template.odo.php @@ -4,564 +4,877 @@ - Error - [[ $error_message ]] + Error — [[ $error_message ]] + + + + + - loadDarkMode(); - - + - -
-
-
-
-
- - - -
+ .arrow-icon { + transition: transform 0.2s ease; + } -
-
- [[ $exception_class ]] -
-

- [[ $error_message]] -

+ /* ── Clickable rows ── */ + .frame-toggle, + .headers-toggle { + display: flex; + align-items: center; + gap: 12px; + padding: 12px 16px; + cursor: pointer; + user-select: none; + } + + .frame-toggle:hover { + background: rgba(0, 0, 0, .02); + } + + html.dark .frame-toggle:hover { + background: rgba(255, 255, 255, .02); + } + + .headers-toggle:hover { + background: rgba(0, 0, 0, .02); + } + + html.dark .headers-toggle:hover { + background: rgba(255, 255, 255, .02); + } + + .exception-pill { + display: inline-flex; + align-items: center; + gap: 6px; + padding: 3px 10px 3px 7px; + border-radius: 6px; + font-size: 11px; + font-weight: 600; + letter-spacing: 0.01em; + background: rgba(225, 29, 72, 0.08); + border: 1px solid rgba(225, 29, 72, 0.18); + color: #e11d48; + } + + html.dark .exception-pill { + background: rgba(251, 113, 133, 0.1); + border-color: rgba(251, 113, 133, 0.2); + color: #fb7185; + } + + .exception-pill-dot { + width: 6px; + height: 6px; + border-radius: 50%; + background: currentColor; + animation: pulse-dot 2s ease infinite; + flex-shrink: 0; + } + + @keyframes pulse-dot { + + 0%, + 100% { + opacity: .8; + transform: scale(1); + } + + 50% { + opacity: .3; + transform: scale(.6); + } + } + + .hero-glow { + position: absolute; + top: -80px; + right: -80px; + width: 500px; + height: 400px; + border-radius: 50%; + pointer-events: none; + } + + .status-badge { + display: inline-flex; + align-items: center; + gap: 6px; + padding: 4px 10px 4px 7px; + border-radius: 6px; + font-size: 11px; + font-weight: 700; + background: rgba(225, 29, 72, 0.09); + border: 1px solid rgba(225, 29, 72, 0.2); + color: #e11d48; + } + + html.dark .status-badge { + background: rgba(251, 113, 133, 0.09); + border-color: rgba(251, 113, 133, 0.2); + color: #fb7185; + } + + .status-badge-dot { + width: 6px; + height: 6px; + border-radius: 50%; + background: currentColor; + animation: pulse-dot 1.8s ease infinite; + } + + .code-line:not(.code-line-error):hover { + background: rgba(0, 0, 0, .025); + } + + html.dark .code-line:not(.code-line-error):hover { + background: rgba(255, 255, 255, .02); + } + + .param-dot-line { + flex-grow: 1; + border-bottom: 1px dashed rgba(0, 0, 0, .1); + margin: 0 8px 4px; + } + + html.dark .param-dot-line { + border-bottom-color: rgba(255, 255, 255, .07); + } + + .line-badge { + display: inline-flex; + align-items: center; + padding: 2px 8px; + border-radius: 5px; + font-size: 10px; + font-weight: 700; + letter-spacing: 0.05em; + background: rgba(225, 29, 72, 0.08); + border: 1px solid rgba(225, 29, 72, 0.18); + color: #e11d48; + } + + html.dark .line-badge { + background: rgba(251, 113, 133, 0.08); + border-color: rgba(251, 113, 133, 0.18); + color: #fb7185; + } + + .route-live-dot { + width: 7px; + height: 7px; + border-radius: 50%; + background: #e11d48; + animation: pulse-dot 1.6s ease infinite; + } + + html.dark .route-live-dot { + background: #fb7185; + } + + .request-bar { + border-top: 1px solid rgba(0, 0, 0, .06); + border-bottom: 1px solid rgba(0, 0, 0, .06); + background: rgba(255, 255, 255, .4); + backdrop-filter: blur(4px); + } + + html.dark .request-bar { + border-top-color: rgba(255, 255, 255, .05); + border-bottom-color: rgba(255, 255, 255, .05); + background: rgba(255, 255, 255, .02); + } + + .frame-count-badge { + display: inline-flex; + align-items: center; + padding: 2px 8px; + border-radius: 99px; + font-size: 10px; + font-weight: 700; + background: rgba(0, 0, 0, .05); + border: 1px solid rgba(0, 0, 0, .07); + color: #64748b; + } + + html.dark .frame-count-badge { + background: rgba(255, 255, 255, .06); + border-color: rgba(255, 255, 255, .06); + color: #94a3b8; + } + + + + + + +
+
+
+ +
+ +
+
+ + [[ $exception_class ]]
-
-
- - -
-
-
- DOPPAR +
+ + + +
+
+ Doppar [[ $doppar_version ]]
-
- PHP +
+ PHP [[ $php_version ]]
+ +

+ [[ $error_message ]] +

-
- - [[ $request_method]] - - [[ $request_url ]] -
- - - - [[ $timestamp ]] + +
+
+
+ [[ $request_method ]] + [[ $request_url ]] + +
-
-
-
- - - - [[ $error_file ]] + +
+
+
+ +
+ [[ $timestamp ]]
- -
-
[[! $contents !]]
+
+ +
+ + + [[ $status_code ]] +
- -
-
-

- - - - Stack Trace -

- -
-
- #include('trace-frames', ['traces' => $traces]) -
+
+ +
+ + [[ $request_method ]] +
-
-
- #include('template-headers', ['headers' => $headers])
-
-
-
- - - - -

System

-
-
-
-
Server
-
[[ $server_software ]]
-
-
-
Platform
-
[[ $platform ]]
-
-
-
+ +
-
-
- - - -

Memory

-
-
-
-
Current Usage
-
[[ number_format($memory_usage / 1024 / 1024, 2) ]] MB
-
-
-
Peak Usage
-
[[ number_format($peack_memory_usage / 1024 / 1024, 2) ]] MB
+ +
+
+
+
+
+
+ [[ $error_file ]] + Line [[ $error_line ]] +
+
+
[[! $contents !]]
-
-
- - - -

User

-
- #if ($user_info) -
-
-
ID
-
[[ $user_info['id'] ]]
-
-
-
Email
-
[[ $user_info['email'] ]]
+ +
+
+
+ + + +

Stack Trace

+
+
- #else -
- - - -

// NO USER

-
- #endif -
-
-
-
-
- - - - -

Request Body

+
+ #include('trace-frames', ['traces' => $traces])
- #if (!empty($request_body)) - - #endif
- #if (!empty($request_body)) - - #else -
- - - - -

// EMPTY REQUEST BODY

-
- #endif -
-
-
- - - -

Routing

+ +
+ #include('template-headers', ['headers' => $headers])
-
- #if (!empty($routing['controller'])) -
-
Controller
-
[[ $routing['controller'] ]] + +
+ +
+
+
+ + + +
+ System +
+
+
+ +
[[ $server_software ]]
+
+
+ +
[[ $platform ]]
+
- #endif - #if (!empty($routing['middleware'])) -
-
Middleware
-
- #foreach ($routing['middleware'] as $mw) - [[ $mw ]] - #endforeach + +
+
+
+ + + +
+ Memory +
+
+
+ +
[[ number_format($memory_usage / 1024 / 1024, 2) ]] MB
+
+
+ +
[[ number_format($peack_memory_usage / 1024 / 1024, 2) ]] MB
+
- #endif + + +
+
+
+ + + +
+ User +
+ #if ($user_info) +
+
+ +
[[ $user_info['id'] ]]
+
+
+ +
[[ $user_info['email'] ]]
+
+
+ #else +
+ + + +

No User

+
+ #endif +
-
-
Route Parameters
- #if (!empty($routing['params'])) -
- #foreach ($routing['params'] as $key => $value) -
-
[[ $key ]]
-
[[ $value ]]
+ +
+
+
+ + +
- #endforeach + Request Body + #if (!empty($request_body)) + + + + #endif +
+ #if (!empty($request_body)) + #else -
- - - +
+ + -

// NO ROUTE PARAMETERS

+

Empty Request Body

#endif
-
- - - - - +
+ + #if(!empty($current_route_action)) +
+ [[ $current_route_action ]] +
+ #else + Closure / No Action + #endif +
+
- + + \ No newline at end of file diff --git a/src/Phaseolies/Error/views/trace-frames.odo.php b/src/Phaseolies/Error/views/trace-frames.odo.php index a6e698f..bde91fe 100644 --- a/src/Phaseolies/Error/views/trace-frames.odo.php +++ b/src/Phaseolies/Error/views/trace-frames.odo.php @@ -1,34 +1,27 @@ -
- #if (empty($traces)) -
No stack trace available
- #else -
- #foreach ($traces as $index => $trace) -
-
- [[ $index + 1 ]] -
-
[[ $trace->getCallSignature() ]]
-
-
[[ $trace->getShortFile() ]]
-
-
- -
- +#if (empty($traces)) +
+

No stack trace available

+
+#else +#foreach ($traces as $index => $trace) +
+ - #endif -
\ No newline at end of file +
+
+ [[! $trace->getCodeLinesContent() !]] +
+
+
+#endforeach +#endif \ No newline at end of file