/** * Execute an action, and in case of an error, erase whatever partial results * have been accumulated, and replace it with an error message and a help screen. */ protected function executeActionWithErrorHandling() { // Verify the CORS header before executing the action if (!$this->handleCORS()) { // handleCORS() has sent a 403, abort return; } // Exit here if the request method was OPTIONS // (assume there will be a followup GET or POST) if ($this->getRequest()->getMethod() === 'OPTIONS') { return; } // In case an error occurs during data output, // clear the output buffer and print just the error information $obLevel = ob_get_level(); ob_start(); $t = microtime(true); try { $this->executeAction(); $isError = false; } catch (Exception $e) { $this->handleException($e); $isError = true; } // Log the request whether or not there was an error $this->logRequest(microtime(true) - $t); // Commit DBs and send any related cookies and headers MediaWiki::preOutputCommit($this->getContext()); // Send cache headers after any code which might generate an error, to // avoid sending public cache headers for errors. $this->sendCacheHeaders($isError); // Executing the action might have already messed with the output // buffers. while (ob_get_level() > $obLevel) { ob_end_flush(); } }