@@ -74,7 +74,6 @@ public function dispatch(Request $request, Response $response, SwooleCoroutineHt
7474
7575 $ yiiResponse = $ app ->getResponse ();
7676 $ yiiResponse ->clear ();
77- $ yiiResponse ->format = YiiResponse::FORMAT_HTML ;
7877 $ this ->prepareLogger ($ app );
7978
8079 try {
@@ -139,7 +138,6 @@ public function dispatch(Request $request, Response $response, SwooleCoroutineHt
139138 $ yiiResponse ->_cookies = null ;
140139 }
141140 $ yiiResponse ->clear ();
142- $ yiiResponse ->format = YiiResponse::FORMAT_HTML ;
143141
144142 // Clear request data
145143 if ($ yiiRequest instanceof YiiRequest) {
@@ -191,28 +189,38 @@ private function handleExceptionWithYii(Throwable $exception, Application $app,
191189 $ errorHandler ->exception = $ exception ;
192190 $ errorHandler ->logException ($ exception );
193191
194- $ bufferLevel = ob_get_level ();
195- ob_start ();
196- try {
197- $ this ->invokeErrorHandlerRenderException ($ errorHandler , $ exception );
198- $ bufferedOutput = ob_get_contents () ?: '' ;
199- } finally {
200- while (ob_get_level () > $ bufferLevel ) {
201- ob_end_clean ();
202- }
203-
204- $ errorHandler ->exception = null ;
205- }
206-
207192 $ yiiResponse = $ app ->getResponse ();
208193 if ($ yiiResponse ->isSent ) {
209194 $ yiiResponse ->isSent = false ;
210195 }
211196
212- if ($ yiiResponse ->content === null ) {
213- $ yiiResponse ->content = $ bufferedOutput ;
197+ if ($ exception instanceof \yii \web \HttpException) {
198+ $ yiiResponse ->setStatusCode ($ exception ->statusCode );
199+ } else {
200+ $ yiiResponse ->setStatusCode (500 );
201+ }
202+
203+ if ($ yiiResponse ->format === YiiResponse::FORMAT_JSON ) {
204+ $ yiiResponse ->data = $ this ->convertExceptionToArray ($ exception , $ errorHandler );
205+ } else {
206+ $ bufferLevel = ob_get_level ();
207+ ob_start ();
208+ try {
209+ $ this ->invokeErrorHandlerRenderException ($ errorHandler , $ exception );
210+ $ bufferedOutput = ob_get_contents () ?: '' ;
211+ } finally {
212+ while (ob_get_level () > $ bufferLevel ) {
213+ ob_end_clean ();
214+ }
215+ }
216+
217+ if ($ yiiResponse ->content === null ) {
218+ $ yiiResponse ->content = $ bufferedOutput ;
219+ }
214220 }
215221
222+ $ errorHandler ->exception = null ;
223+
216224 if ($ this ->isWritable ($ swooleResponse )) {
217225 $ this ->finalizeResponse ($ swooleResponse , $ yiiResponse );
218226 }
@@ -225,6 +233,40 @@ private function handleExceptionWithYii(Throwable $exception, Application $app,
225233 }
226234 }
227235
236+ private function convertExceptionToArray (Throwable $ exception , ErrorHandler $ errorHandler ): array
237+ {
238+ if (!defined ('YII_DEBUG ' ) || !YII_DEBUG ) {
239+ if (!($ exception instanceof \yii \base \UserException) && !($ exception instanceof \yii \web \HttpException)) {
240+ $ exception = new \yii \web \HttpException (500 , Yii::t ('yii ' , 'An internal server error occurred. ' ));
241+ }
242+ }
243+
244+ $ array = [
245+ 'name ' => ($ exception instanceof \yii \base \Exception || $ exception instanceof \yii \base \ErrorException)
246+ ? $ exception ->getName ()
247+ : 'Exception ' ,
248+ 'message ' => $ exception ->getMessage (),
249+ 'code ' => $ exception ->getCode (),
250+ ];
251+
252+ if ($ exception instanceof \yii \web \HttpException) {
253+ $ array ['status ' ] = $ exception ->statusCode ;
254+ }
255+
256+ if (defined ('YII_DEBUG ' ) && YII_DEBUG ) {
257+ $ array ['type ' ] = get_class ($ exception );
258+ $ array ['file ' ] = $ exception ->getFile ();
259+ $ array ['line ' ] = $ exception ->getLine ();
260+ $ array ['stack-trace ' ] = explode ("\n" , $ exception ->getTraceAsString ());
261+ }
262+
263+ if (($ prev = $ exception ->getPrevious ()) !== null ) {
264+ $ array ['previous ' ] = $ this ->convertExceptionToArray ($ prev , $ errorHandler );
265+ }
266+
267+ return $ array ;
268+ }
269+
228270 private function invokeErrorHandlerRenderException (ErrorHandler $ errorHandler , Throwable $ exception ): void
229271 {
230272 if (self ::$ renderExceptionMethod === null ) {
0 commit comments