print MWExceptionRenderer::getHTML( $e );
exit;
}
-
}
MWExceptionHandler::handleException( $e );
$lbFactory->hasOrMadeRecentMasterChanges( INF )
) ? self::getUrlDomainDistance( $output->getRedirect(), $context ) : false;
+ $allowHeaders = !( $output->isDisabled() || headers_sent() );
if ( $urlDomainDistance === 'local' || $urlDomainDistance === 'remote' ) {
// OutputPage::output() will be fast; $postCommitWork will not be useful for
// masking the latency of syncing DB positions accross all datacenters synchronously.
$flags = $lbFactory::SHUTDOWN_CHRONPROT_ASYNC;
$cpPosTime = microtime( true );
// Client's next request should see 1+ positions with this DBMasterPos::asOf() time
- if ( $urlDomainDistance === 'local' ) {
+ if ( $urlDomainDistance === 'local' && $allowHeaders ) {
// Client will stay on this domain, so set an unobtrusive cookie
$expires = time() + ChronologyProtector::POSITION_TTL;
$options = [ 'prefix' => '' ];
// OutputPage::output() is fairly slow; run it in $postCommitWork to mask
// the latency of syncing DB positions accross all datacenters synchronously
$flags = $lbFactory::SHUTDOWN_CHRONPROT_SYNC;
- if ( $lbFactory->hasOrMadeRecentMasterChanges( INF ) ) {
+ if ( $lbFactory->hasOrMadeRecentMasterChanges( INF ) && $allowHeaders ) {
$cpPosTime = microtime( true );
// Set a cookie in case the DB position store cannot sync accross datacenters.
// This will at least cover the common case of the user staying on the domain.
* @since 1.26
*/
public function doPostOutputShutdown( $mode = 'normal' ) {
- $timing = $this->context->getTiming();
- $timing->mark( 'requestShutdown' );
-
- // Show visible profiling data if enabled (which cannot be post-send)
- Profiler::instance()->logDataPageOutputOnly();
+ // Perform the last synchronous operations...
+ try {
+ // Record backend request timing
+ $timing = $this->context->getTiming();
+ $timing->mark( 'requestShutdown' );
+ // Show visible profiling data if enabled (which cannot be post-send)
+ Profiler::instance()->logDataPageOutputOnly();
+ } catch ( Exception $e ) {
+ // An error may already have been shown in run(), so just log it to be safe
+ MWExceptionHandler::rollbackMasterChangesAndLog( $e );
+ }
+ // Defer everything else if possible...
$callback = function () use ( $mode ) {
try {
$this->restInPeace( $mode );
} catch ( Exception $e ) {
- MWExceptionHandler::handleException( $e );
+ // If this is post-send, then displaying errors can cause broken HTML
+ MWExceptionHandler::rollbackMasterChangesAndLog( $e );
}
};
- // Defer everything else...
if ( function_exists( 'register_postsend_function' ) ) {
// https://github.com/facebook/hhvm/issues/1230
register_postsend_function( $callback );
// ATTENTION: This hook is likely to be removed soon due to overall design of the system.
if ( Hooks::run( 'BeforeHttpsRedirect', [ $this->context, &$redirUrl ] ) ) {
-
if ( $request->wasPosted() ) {
// This is weird and we'd hope it almost never happens. This
// means that a POST came in via HTTP and policy requires us