I'm throwing an exception from within my template's code, somewhere near the end of my templates:
...
{{ offer.throwError() }}
...
Offer::throwError:
public function throwError() {
$foo = $this->getAdvantageText()->getFoo(); //fatal error
throw new \Exception("blah"); //only exception
}
Having not customized anything I expect to have an error page rendered as response (using Twig's default ExceptionController which we in fact want to override). When Offer::getAdvantageText() is === null a FatalErrorException is raised and the error page contents are written directly into the markup at the place where the exception is thrown. When I just throw the custom exception, it works as expected (a single error page is shown). When I debug into ExceptionController, it is supposed to explicitly clear the output buffer:
Twig/ExceptionController:
protected function getAndCleanOutputBuffering($startObLevel)
{
if (ob_get_level() <= $startObLevel) {
return '';
}
Response::closeOutputBuffers($startObLevel + 1, true);
return ob_get_clean();
}
but in all my fatal error cases ob_get_level is <= $startObLevel (handed over by kernel, in my case "2"). We don't have application / gateway caching in place (yet). When I manually clear the output buffer in that situation, the page is "cleared" and I get a single error page response as expected. As far as I can see there's no fragment rendering in place (that would've issued a subrequest).
I thought about utilizing the kernel.exception event and clear everything on my own but I think just customizing the controller should do the trick anyway. It seems that the "fatal" error is interfering with the ob-stack of Symfony's kernel but I can't see how to work around that issue.
I've got a preliminary solution to address that issue. In my custom exception controller I also overwrite the getAndCleanOutputBuffering method:
protected function getAndCleanOutputBuffering($startObLevel)
{
Response::closeOutputBuffers($startObLevel + 1, false);
return ob_get_clean();
}
If Response::closeOutputBuffers
' second argument is set to false
it will call an "ob_end_clean" instead of "ob_end_flush" under the hood. The already rendered content is lost however.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.