Пример #1
0
 /**
  * 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
     ob_start();
     $t = microtime(true);
     try {
         $this->executeAction();
     } catch (Exception $e) {
         // Allow extra cleanup and logging
         wfRunHooks('ApiMain::onException', array($this, $e));
         // Log it
         if ($e instanceof MWException && !$e instanceof UsageException) {
             global $wgLogExceptionBacktrace;
             if ($wgLogExceptionBacktrace) {
                 wfDebugLog('exception', $e->getLogMessage() . "\n" . $e->getTraceAsString() . "\n");
             } else {
                 wfDebugLog('exception', $e->getLogMessage());
             }
         }
         // Handle any kind of exception by outputting properly formatted error message.
         // If this fails, an unhandled exception should be thrown so that global error
         // handler will process and log it.
         $errCode = $this->substituteResultWithError($e);
         // Error results should not be cached
         $this->setCacheMode('private');
         $response = $this->getRequest()->response();
         $headerStr = 'MediaWiki-API-Error: ' . $errCode;
         if ($e->getCode() === 0) {
             $response->header($headerStr);
         } else {
             $response->header($headerStr, true, $e->getCode());
         }
         // Reset and print just the error message
         ob_clean();
         // If the error occurred during printing, do a printer->profileOut()
         $this->mPrinter->safeProfileOut();
         $this->printResult(true);
     }
     // Log the request whether or not there was an error
     $this->logRequest(microtime(true) - $t);
     // Send cache headers after any code which might generate an error, to
     // avoid sending public cache headers for errors.
     $this->sendCacheHeaders();
     if ($this->mPrinter->getIsHtml() && !$this->mPrinter->isDisabled()) {
         echo wfReportTime();
     }
     ob_end_flush();
 }
Пример #2
0
 /**
  * Replace the result data with the information about an exception.
  * Returns the error code
  * @param $e Exception
  * @return string
  */
 protected function substituteResultWithError($e)
 {
     global $wgShowHostnames;
     $result = $this->getResult();
     // Printer may not be initialized if the extractRequestParams() fails for the main module
     if (!isset($this->mPrinter)) {
         // The printer has not been created yet. Try to manually get formatter value.
         $value = $this->getRequest()->getVal('format', self::API_DEFAULT_FORMAT);
         if (!$this->mModuleMgr->isDefined($value, 'format')) {
             $value = self::API_DEFAULT_FORMAT;
         }
         $this->mPrinter = $this->createPrinterByName($value);
     }
     // Printer may not be able to handle errors. This is particularly
     // likely if the module returns something for getCustomPrinter().
     if (!$this->mPrinter->canPrintErrors()) {
         $this->mPrinter->safeProfileOut();
         $this->mPrinter = $this->createPrinterByName(self::API_DEFAULT_FORMAT);
     }
     // Update raw mode flag for the selected printer.
     $result->setRawMode($this->mPrinter->getNeedsRawData());
     if ($e instanceof UsageException) {
         // User entered incorrect parameters - print usage screen
         $errMessage = $e->getMessageArray();
         // Only print the help message when this is for the developer, not runtime
         if ($this->mPrinter->getWantsHelp() || $this->mAction == 'help') {
             ApiResult::setContent($errMessage, $this->makeHelpMsg());
         }
     } else {
         global $wgShowSQLErrors, $wgShowExceptionDetails;
         // Something is seriously wrong
         if ($e instanceof DBQueryError && !$wgShowSQLErrors) {
             $info = 'Database query error';
         } else {
             $info = "Exception Caught: {$e->getMessage()}";
         }
         $errMessage = array('code' => 'internal_api_error_' . get_class($e), 'info' => $info);
         ApiResult::setContent($errMessage, $wgShowExceptionDetails ? "\n\n{$e->getTraceAsString()}\n\n" : '');
     }
     // Remember all the warnings to re-add them later
     $oldResult = $result->getData();
     $warnings = isset($oldResult['warnings']) ? $oldResult['warnings'] : null;
     $result->reset();
     $result->disableSizeCheck();
     // Re-add the id
     $requestid = $this->getParameter('requestid');
     if (!is_null($requestid)) {
         $result->addValue(null, 'requestid', $requestid);
     }
     if ($wgShowHostnames) {
         // servedby is especially useful when debugging errors
         $result->addValue(null, 'servedby', wfHostName());
     }
     if ($warnings !== null) {
         $result->addValue(null, 'warnings', $warnings);
     }
     $result->addValue(null, 'error', $errMessage);
     return $errMessage['code'];
 }
Пример #3
0
 /**
  * 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()
 {
     // In case an error occurs during data output,
     // clear the output buffer and print just the error information
     ob_start();
     try {
         $this->executeAction();
     } catch (Exception $e) {
         // Log it
         if ($e instanceof MWException) {
             wfDebugLog('exception', $e->getLogMessage());
         }
         // Handle any kind of exception by outputing properly formatted error message.
         // If this fails, an unhandled exception should be thrown so that global error
         // handler will process and log it.
         $errCode = $this->substituteResultWithError($e);
         // Error results should not be cached
         $this->setCacheMode('private');
         $response = $this->getRequest()->response();
         $headerStr = 'MediaWiki-API-Error: ' . $errCode;
         if ($e->getCode() === 0) {
             $response->header($headerStr);
         } else {
             $response->header($headerStr, true, $e->getCode());
         }
         // Reset and print just the error message
         ob_clean();
         // If the error occured during printing, do a printer->profileOut()
         $this->mPrinter->safeProfileOut();
         $this->printResult(true);
     }
     // Send cache headers after any code which might generate an error, to
     // avoid sending public cache headers for errors.
     $this->sendCacheHeaders();
     if ($this->mPrinter->getIsHtml() && !$this->mPrinter->isDisabled()) {
         echo wfReportTime();
     }
     ob_end_flush();
 }