Skip to content

Commit f7fbb8f

Browse files
author
Greg Bowler
committed
wip: the main error flow is defined for #299
1 parent 211f4c2 commit f7fbb8f

File tree

1 file changed

+79
-10
lines changed

1 file changed

+79
-10
lines changed

src/Middleware/Lifecycle.php

Lines changed: 79 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -4,13 +4,17 @@
44
use Gt\Config\ConfigFactory;
55
use Gt\Config\ConfigSection;
66
use Gt\Http\RequestFactory;
7+
use Gt\Http\Response;
8+
use Gt\Http\ResponseFactory;
79
use Gt\Http\StatusCode;
10+
use Gt\Http\Stream;
811
use Gt\Logger\Log;
912
use Gt\WebEngine\Debug\Timer;
1013
use Psr\Http\Message\ResponseInterface;
1114
use Psr\Http\Message\ServerRequestInterface;
1215
use Psr\Http\Server\MiddlewareInterface;
1316
use Psr\Http\Server\RequestHandlerInterface;
17+
use Throwable;
1418

1519
/**
1620
* The fundamental purpose of any PHP framework is to provide a mechanism for
@@ -38,8 +42,11 @@
3842
*/
3943
class Lifecycle implements MiddlewareInterface {
4044
private Timer $timer;
45+
private Throwable $throwable;
4146

4247
public function start():void {
48+
set_error_handler($this->error(...), E_ALL);
49+
4350
// set_error_handler(function($errno, $errstr, $errfile, $errline) {
4451
// throw new \Exception($errstr, $errno, 0, $errfile, $errline);
4552
// }, E_WARNING);
@@ -77,7 +84,25 @@ public function start():void {
7784

7885
// The request and request handler are passed to the PSR-15 process function,
7986
// which will return our PSR-7 HTTP Response.
80-
$response = $this->process($request, $handler);
87+
try {
88+
$response = $this->process($request, $handler);
89+
}
90+
catch(Throwable $throwable) {
91+
// TODO: $response = $this->process($request, $errorHandler)
92+
// There should be some sort of magical error handler created at this point,
93+
// but most of the refactoring of the RequestHandler::handle() function can
94+
// be shared to this other Handler. This kills two birds with one stone, as
95+
// when generating the new response, it should still have user-code executing
96+
// wherever possible. Question: should _common still fire? I don't think so...
97+
/// ... but _error should!
98+
$response = $this->responseFromThrowable($throwable);
99+
100+
$this->throwable = $throwable;
101+
trigger_error(
102+
$throwable->getMessage(),
103+
E_USER_ERROR,
104+
);
105+
}
81106

82107
// Now we can finish the HTTP lifecycle by providing the HTTP response for
83108
// outputting to the browser, along with the buffer so we can display the
@@ -99,6 +124,57 @@ public function process(
99124
return $handler->handle($request);
100125
}
101126

127+
public function error(
128+
int $errno,
129+
string $errstr,
130+
?string $errfile = null,
131+
?int $errline = null,
132+
?array $errcontext = null,
133+
):bool {
134+
$params = ["error", $errstr];
135+
if(isset($this->throwable)) {
136+
array_push($params, $this->throwable, get_class($this->throwable));
137+
}
138+
call_user_func_array($this->debugOutput(...), $params);
139+
return true;
140+
}
141+
142+
public function debugOutput(
143+
string $name,
144+
string $message,
145+
mixed $detail = null,
146+
?string $detailName = null,
147+
):void {
148+
$detailJs = "";
149+
if(!is_null($detail)) {
150+
if(!is_null($detailName)) {
151+
$detailJs .= "console.group(\"$detailName\");";
152+
}
153+
// $detailJs .= "console.log(`" . print_r($detail, true) . "`)";
154+
if(!is_null($detailName)) {
155+
$detailJs .= "console.groupEnd();";
156+
}
157+
}
158+
$js = <<<JS
159+
<script class="webengine-debug--$name">
160+
console.group("%cphp.gt/webengine", "display: inline-block; padding: 0.5em 1em; background: #26a5e3; color: white; cursor: pointer");
161+
console.info(`$message`);
162+
$detailJs
163+
console.groupEnd();
164+
</script>
165+
JS;
166+
$js = str_replace("</script", "<\\/script", $js);
167+
echo $js;
168+
}
169+
170+
public function responseFromThrowable(Throwable $throwable):Response {
171+
$response = new Response();
172+
$body = new Stream();
173+
$body->write("errrrrrrrrrrror!");
174+
$response = $response->withBody($body);
175+
return $response;
176+
}
177+
102178
public function finish(
103179
ResponseInterface $response,
104180
ConfigSection $appConfig
@@ -127,15 +203,8 @@ public function finish(
127203
}
128204

129205
if(strlen($buffer) > 0) {
130-
$buffer = str_replace("</script", "<\\/script", $buffer);
131-
$js = <<<JS
132-
<script id="webengine-debug">
133-
console.group("%cphp.gt/webengine", "display: inline-block; padding: 0.5em 1em; background: #26a5e3; color: white; cursor: pointer");
134-
console.info(`$buffer`);
135-
console.groupEnd();
136-
</script>
137-
JS;
138-
echo $js;
206+
$this->debugOutput("buffer", $buffer);
207+
exit;
139208
}
140209

141210
// The very last thing that's done before the script ends is to stop the Timer,

0 commit comments

Comments
 (0)