@recaptime-dev's working patches + fork for Phorge, a community fork of Phabricator. (Upstream dev and stable branches are at upstream/main and upstream/stable respectively.) hq.recaptime.dev/wiki/Phorge
phorge phabricator
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

Try harder to present display/rendering exceptions to the user using standard exception handling

Summary:
Ref T13250. When exceptions occur in display/rendering/writing, they currently go straight to the fallback handler. This is a minimal handler which doesn't show a stack trace or include any debugging details.

In some cases, we have to do this: some of these exceptions prevent us from building a normal page. For example, if the menu bar has a hard fatal in it, we aren't going to be able to build a nice exception page with a menu bar no matter how hard we try.

However, in many cases the error is mundane: something detected something invalid and raised an exception during rendering. In these cases there's no problem with the page chrome or the rendering pathway itself, just with rendering the page data.

When we get a rendering/response exception, try a second time to build a nice normal exception page. This will often work. If it doesn't work, fall back as before.

Test Plan:
- Forced the error from T13250 by applying D20136 but not D20134.
- Before:

{F6205001}

- After:

{F6205002}

Reviewers: amckinley

Reviewed By: amckinley

Maniphest Tasks: T13250

Differential Revision: https://secure.phabricator.com/D20137

+43 -4
+43 -4
src/aphront/configuration/AphrontApplicationConfiguration.php
··· 282 282 } 283 283 } catch (Exception $ex) { 284 284 $original_exception = $ex; 285 - $response = $this->handleThrowable($ex); 286 285 } catch (Throwable $ex) { 287 286 $original_exception = $ex; 288 - $response = $this->handleThrowable($ex); 289 287 } 290 288 291 289 try { 290 + if ($original_exception) { 291 + $response = $this->handleThrowable($original_exception); 292 + } 293 + 292 294 $response = $this->produceResponse($request, $response); 293 295 $response = $controller->willSendResponse($response); 294 296 $response->setRequest($request); 295 297 296 298 self::writeResponse($sink, $response); 297 - } catch (Exception $ex) { 299 + } catch (Exception $response_exception) { 300 + // If we encountered an exception while building a normal response, then 301 + // encountered another exception while building a response for the first 302 + // exception, just throw the original exception. It is more likely to be 303 + // useful and point at a root cause than the second exception we ran into 304 + // while telling the user about it. 298 305 if ($original_exception) { 299 306 throw $original_exception; 300 307 } 301 - throw $ex; 308 + 309 + // If we built a response successfully and then ran into an exception 310 + // trying to render it, try to handle and present that exception to the 311 + // user using the standard handler. 312 + 313 + // The problem here might be in rendering (more common) or in the actual 314 + // response mechanism (less common). If it's in rendering, we can likely 315 + // still render a nice exception page: the majority of rendering issues 316 + // are in main page content, not content shared with the exception page. 317 + 318 + $handling_exception = null; 319 + try { 320 + $response = $this->handleThrowable($response_exception); 321 + 322 + $response = $this->produceResponse($request, $response); 323 + $response = $controller->willSendResponse($response); 324 + $response->setRequest($request); 325 + 326 + self::writeResponse($sink, $response); 327 + } catch (Exception $ex) { 328 + $handling_exception = $ex; 329 + } catch (Throwable $ex) { 330 + $handling_exception = $ex; 331 + } 332 + 333 + // If we didn't have any luck with that, raise the original response 334 + // exception. As above, this is the root cause exception and more likely 335 + // to be useful. This will go to the fallback error handler at top 336 + // level. 337 + 338 + if ($handling_exception) { 339 + throw $response_exception; 340 + } 302 341 } 303 342 304 343 return $response;