Exemple #1
0
 /**
  * Returns catched error/warning message.
  * @param  \ErrorException  catched error
  * @return bool
  */
 public static function catchError(&$error)
 {
     if (!self::$enabled && self::$lastError !== FALSE) {
         restore_error_handler();
     }
     $error = self::$lastError;
     self::$lastError = FALSE;
     return (bool) $error;
 }
Exemple #2
0
	/**
	 * Enables displaying or logging errors and exceptions.
	 * @param  mixed         production, development mode, autodetection or IP address(es).
	 * @param  string        error log directory; enables logging in production mode
	 * @param  string        administrator email; enables email sending in production mode
	 * @return void
	 */
	public static function enable($mode = NULL, $logDirectory = NULL, $email = NULL)
	{
		error_reporting(E_ALL | E_STRICT);

		// production/development mode detection
		if (is_bool($mode)) {
			self::$productionMode = $mode;

		} elseif (is_string($mode)) { // IP adresses
			$mode = preg_split('#[,\s]+#', $mode);
		}

		if (is_array($mode)) { // IP adresses
			self::$productionMode = !isset($_SERVER['REMOTE_ADDR']) || !in_array($_SERVER['REMOTE_ADDR'], $mode, TRUE);
		}

		if (self::$productionMode === self::DETECT) {
			if (class_exists('Nette\Environment')) {
				self::$productionMode = Environment::isProduction();

			} elseif (isset($_SERVER['SERVER_ADDR']) || isset($_SERVER['LOCAL_ADDR'])) { // IP address based detection
				$addr = isset($_SERVER['SERVER_ADDR']) ? $_SERVER['SERVER_ADDR'] : $_SERVER['LOCAL_ADDR'];
				$oct = explode('.', $addr);
				self::$productionMode = $addr !== '::1' && (count($oct) !== 4 || ($oct[0] !== '10' && $oct[0] !== '127' && ($oct[0] !== '172' || $oct[1] < 16 || $oct[1] > 31)
					&& ($oct[0] !== '169' || $oct[1] !== '254') && ($oct[0] !== '192' || $oct[1] !== '168')));

			} else {
				self::$productionMode = !self::$consoleMode;
			}
		}

		// logging configuration
		if (self::$productionMode && $logDirectory !== FALSE) {
			if (is_string($logDirectory)) {
				self::$logDirectory = $logDirectory;
			} else {
				self::$logDirectory = defined('APP_DIR') ? APP_DIR . '/../log/' : getcwd() . '/log';
			}
			ini_set('error_log', self::$logDirectory . '/php_error.log');
		}

		// php configuration
		if (function_exists('ini_set')) {
			ini_set('display_errors', !self::$productionMode); // or 'stderr'
			ini_set('html_errors', FALSE);
			ini_set('log_errors', FALSE);

		} elseif (ini_get('display_errors') != !self::$productionMode && ini_get('display_errors') !== (self::$productionMode ? 'stderr' : 'stdout')) { // intentionally ==
			throw new \NotSupportedException('Function ini_set() must be enabled.');
		}

		if ($email) {
			if (!is_string($email)) {
				throw new \InvalidArgumentException('E-mail address must be a string.');
			}
			self::$email = $email;
		}

		if (!defined('E_DEPRECATED')) {
			define('E_DEPRECATED', 8192);
		}

		if (!defined('E_USER_DEPRECATED')) {
			define('E_USER_DEPRECATED', 16384);
		}

		if (!self::$enabled) {
			register_shutdown_function(array(__CLASS__, '_shutdownHandler'));
			set_exception_handler(array(__CLASS__, '_exceptionHandler'));
			set_error_handler(array(__CLASS__, '_errorHandler'));
			self::$enabled = TRUE;
		}
	}
Exemple #3
0
 /**
  * Logs or displays exception.
  * @param  \Exception
  * @param  bool  is writing to standard output buffer allowed?
  * @return void
  */
 public static function processException(\Exception $exception, $outputAllowed = FALSE)
 {
     if (!self::$enabled) {
         return;
     } elseif (self::$logFile) {
         try {
             $hash = md5($exception);
             self::log("PHP Fatal error: Uncaught " . str_replace("Stack trace:\n" . $exception->getTraceAsString(), '', $exception));
             foreach (new \DirectoryIterator(dirname(self::$logFile)) as $entry) {
                 if (strpos($entry, $hash)) {
                     $skip = TRUE;
                     break;
                 }
             }
             $file = dirname(self::$logFile) . "/exception " . @date('Y-m-d H-i-s') . " {$hash}.html";
             if (empty($skip) && (self::$logHandle = @fopen($file, 'w'))) {
                 ob_start();
                 // double buffer prevents sending HTTP headers in some PHP
                 ob_start(array(__CLASS__, '_writeFile'), 1);
                 self::_paintBlueScreen($exception);
                 ob_end_flush();
                 ob_end_clean();
                 fclose(self::$logHandle);
             }
             if (self::$sendEmails) {
                 self::sendEmail((string) $exception);
             }
         } catch (\Exception $e) {
             if (!headers_sent()) {
                 header('HTTP/1.1 500 Internal Server Error');
             }
             echo 'Nette\\Debug fatal error: ', get_class($e), ': ', ($e->getCode() ? '#' . $e->getCode() . ' ' : '') . $e->getMessage(), "\n";
             exit;
         }
     } elseif (self::$productionMode) {
         // be quiet
     } elseif (self::$consoleMode) {
         // dump to console
         if ($outputAllowed) {
             echo "{$exception}\n";
         }
     } elseif (self::$firebugDetected && self::$ajaxDetected && !headers_sent()) {
         // AJAX mode
         self::fireLog($exception, self::EXCEPTION);
     } elseif ($outputAllowed) {
         // dump to browser
         if (!headers_sent()) {
             @ob_end_clean();
             while (ob_get_level() && @ob_end_clean()) {
             }
             header_remove('Content-Encoding');
         }
         self::_paintBlueScreen($exception);
     } elseif (self::$firebugDetected && !headers_sent()) {
         self::fireLog($exception, self::EXCEPTION);
     }
     foreach (self::$onFatalError as $handler) {
         call_user_func($handler, $exception);
     }
 }
Exemple #4
0
 /**
  * Starts catching potential errors/warnings.
  * @return void
  */
 public static function tryError()
 {
     error_reporting(0);
     $old = self::$scream;
     self::$scream = FALSE;
     trigger_error('');
     // "reset" error_get_last
     self::$scream = $old;
 }