/** * Handler to catch uncaught exception. * @param \Exception * @return void * @internal */ public static function _exceptionHandler(\Exception $exception) { if (!headers_sent()) { // for PHP < 5.2.4 $protocol = isset($_SERVER['SERVER_PROTOCOL']) ? $_SERVER['SERVER_PROTOCOL'] : 'HTTP/1.1'; $code = isset($_SERVER['HTTP_USER_AGENT']) && strpos($_SERVER['HTTP_USER_AGENT'], 'MSIE ') !== FALSE ? 503 : 500; header("{$protocol} {$code}", TRUE, $code); } try { if (self::$productionMode) { try { self::log($exception, self::ERROR); } catch (\Exception $e) { echo 'FATAL ERROR: unable to log error'; } if (self::$consoleMode) { echo "ERROR: the server encountered an internal error and was unable to complete your request.\n"; } elseif (self::isHtmlMode()) { require __DIR__ . '/templates/error.phtml'; } } else { if (self::$consoleMode) { // dump to console echo "{$exception}\n"; if ($file = self::log($exception)) { echo "(stored in {$file})\n"; if (self::$browser) { exec(self::$browser . ' ' . escapeshellarg($file)); } } } elseif (self::isHtmlMode()) { // dump to browser self::$blueScreen->render($exception); if (self::$bar) { self::$bar->render(); } } elseif (!self::fireLog($exception)) { // AJAX or non-HTML mode $file = self::log($exception, self::ERROR); if (!headers_sent()) { header("X-Nette-Error-Log: {$file}"); } } } foreach (self::$onFatalError as $handler) { call_user_func($handler, $exception); } } catch (\Exception $e) { if (self::$productionMode) { echo self::isHtmlMode() ? '<meta name=robots content=noindex>FATAL ERROR' : 'FATAL ERROR'; } else { echo "FATAL ERROR: thrown ", get_class($e), ': ', $e->getMessage(), "\nwhile processing ", get_class($exception), ': ', $exception->getMessage(), "\n"; } } self::$enabled = FALSE; // un-register shutdown function exit(254); }
/** * Handler to catch uncaught exception. * @param \Exception * @return void * @internal */ public static function _exceptionHandler(\Exception $exception) { if (!headers_sent()) { // for PHP < 5.2.4 header('HTTP/1.1 500 Internal Server Error'); } try { if (self::$productionMode) { try { self::log($exception, self::ERROR); } catch (\Exception $e) { echo 'FATAL ERROR: unable to log error'; } if (self::$consoleMode) { echo "ERROR: the server encountered an internal error and was unable to complete your request.\n"; } elseif (self::isHtmlMode()) { require __DIR__ . '/templates/error.phtml'; } } else { if (self::$consoleMode) { // dump to console echo "{$exception}\n"; } elseif (self::isHtmlMode()) { // dump to browser self::$blueScreen->render($exception); if (self::$bar) { self::$bar->render(); } } elseif (!self::fireLog($exception, self::ERROR)) { // AJAX or non-HTML mode self::log($exception); } } foreach (self::$onFatalError as $handler) { call_user_func($handler, $exception); } } catch (\Exception $e) { if (self::$productionMode) { echo self::isHtmlMode() ? '<meta name=robots content=noindex>FATAL ERROR' : 'FATAL ERROR'; } else { echo "FATAL ERROR: thrown ", get_class($e), ': ', $e->getMessage(), "\nwhile processing ", get_class($exception), ': ', $exception->getMessage(), "\n"; } } self::$enabled = FALSE; // un-register shutdown function exit(255); }
/** * Handler to catch uncaught exception. * @param \Exception * @return void * @internal */ public static function _exceptionHandler(\Exception $exception) { if (!headers_sent()) { // for PHP < 5.2.4 header('HTTP/1.1 500 Internal Server Error'); } $htmlMode = !self::$ajaxDetected && !preg_match('#^Content-Type: (?!text/html)#im', implode("\n", headers_list())); try { if (self::$productionMode) { self::log($exception, self::ERROR); if (self::$consoleMode) { echo "ERROR: the server encountered an internal error and was unable to complete your request.\n"; } elseif ($htmlMode) { require __DIR__ . '/templates/error.phtml'; } } else { if (self::$consoleMode) { // dump to console echo "{$exception}\n"; } elseif ($htmlMode) { // dump to browser self::$blueScreen->render($exception); if (self::$bar) { self::$bar->render(); } } elseif (!self::fireLog($exception, self::ERROR)) { // AJAX or non-HTML mode self::log($exception); } } foreach (self::$onFatalError as $handler) { call_user_func($handler, $exception); } } catch (\Exception $e) { echo "\nNette\\Debug FATAL ERROR: thrown ", get_class($e), ': ', $e->getMessage(), "\nwhile processing ", get_class($exception), ': ', $exception->getMessage(), "\n"; } self::$enabled = FALSE; // un-register shutdown function exit(255); }
/** * Logs message or exception to file (if not disabled) and sends email notification (if enabled). * * @param string|Exception * @param int one of constant Debugger::INFO, WARNING, ERROR (sends email), CRITICAL (sends email) * * @return string logged error filename */ public static function log($message, $priority = self::INFO) { if (self::$logDirectory === false) { return; } elseif (!self::$logDirectory) { throw new Nette\InvalidStateException('Logging directory is not specified in Nette\\Diagnostics\\Debugger::$logDirectory.'); } if ($message instanceof \Exception) { $exception = $message; $message = ($message instanceof Nette\FatalErrorException ? 'Fatal error: ' . $exception->getMessage() : get_class($exception) . ": " . $exception->getMessage()) . " in " . $exception->getFile() . ":" . $exception->getLine(); $hash = md5($exception); $exceptionFilename = "exception-" . @date('Y-m-d-H-i-s') . "-{$hash}.html"; foreach (new \DirectoryIterator(self::$logDirectory) as $entry) { if (strpos($entry, $hash)) { $exceptionFilename = $entry; $saved = true; break; } } } self::$logger->log(array(@date('[Y-m-d H-i-s]'), trim($message), self::$source ? ' @ ' . self::$source : null, !empty($exceptionFilename) ? ' @@ ' . $exceptionFilename : null), $priority); if (!empty($exceptionFilename)) { $exceptionFilename = self::$logDirectory . '/' . $exceptionFilename; if (empty($saved) && ($logHandle = @fopen($exceptionFilename, 'w'))) { ob_start(); // double buffer prevents sending HTTP headers in some PHP ob_start(function ($buffer) use($logHandle) { fwrite($logHandle, $buffer); }, 4096); self::$blueScreen->render($exception); ob_end_flush(); ob_end_clean(); fclose($logHandle); } return strtr($exceptionFilename, '\\/', DIRECTORY_SEPARATOR . DIRECTORY_SEPARATOR); } }
/** * Logs error into database, URL is generated automatically * @param string $lstErrorTpName * @param string $message * @param string $insProcessId * @return \Nette\Database\Table\ActiveRow */ public function logError($message, $lstErrorTpName = null, $insProcessId = 'Logger::logError()') { $file_content = null; $now = new \DateTime(); if ($message instanceof \Exception) { $lstErrorTpName = $lstErrorTpName ?: 'exception'; $exception = $message; $message = ($message instanceof Nette\FatalErrorException ? 'Fatal error: ' . $exception->getMessage() : get_class($exception) . ": " . $exception->getMessage()) . ($exception->getCode() ? " #" . $exception->getCode() : ''); // Check if this exception has been submitted recently $isReported = $this->logErrorEntity->getTable()->where("message", $message)->where("reported_flag", 0)->where("ins_dt >= ?", $now->modify('-3 hours'))->fetch(); if (!$isReported) { $blueScreen = new ND\BlueScreen(); ob_start(); ob_start(); $blueScreen->render($exception); $file_content = ob_get_contents(); ob_end_clean(); ob_end_clean(); } } else { $isReported = $this->logErrorEntity->getTable()->where("message", $message)->where("reported_flag", 0)->where("url", $this->httpRequest->getUrl())->where("ins_dt >= ?", $now->modify('-3 hours'))->fetch(); } $lstErrorTpName = $lstErrorTpName ?: 'error'; if ($isReported) { $isReportedArray = $isReported->toArray(); $cnt = 1 + $isReportedArray['occured_cnt']; $isReported->update(array("occured_cnt" => $cnt, "upd_process_id" => "REPEATED_EXCEPTION_OCCURENCE")); return $isReported; } $logVisitId = $this->lastLogVisitRow ? $this->lastLogVisitRow->id : -1; $errorTp = $this->getErrorTpByName($lstErrorTpName); return $this->logErrorEntity->insert(array("error_tp_id" => $errorTp->id, "message" => $message, "file_content" => $file_content, "url" => $this->httpRequest->getUrl(), "log_visit_id" => $logVisitId, "post_query" => $this->createQueryString($this->httpRequest->getPost()), "ins_dt" => new \DateTime(), "ins_process_id" => $insProcessId)); }