44use Gt \Config \ConfigFactory ;
55use Gt \Config \ConfigSection ;
66use Gt \Http \RequestFactory ;
7+ use Gt \Http \Response ;
8+ use Gt \Http \ResponseFactory ;
79use Gt \Http \StatusCode ;
10+ use Gt \Http \Stream ;
811use Gt \Logger \Log ;
912use Gt \WebEngine \Debug \Timer ;
1013use Psr \Http \Message \ResponseInterface ;
1114use Psr \Http \Message \ServerRequestInterface ;
1215use Psr \Http \Server \MiddlewareInterface ;
1316use Psr \Http \Server \RequestHandlerInterface ;
17+ use Throwable ;
1418
1519/**
1620 * The fundamental purpose of any PHP framework is to provide a mechanism for
3842 */
3943class 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