<commit_before><?php namespace DavBfr\CF;
/**
 * Copyright (C) 2013-2015 <NAME>
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
 **/

use Exception;

class ErrorHandler {
	private static $instance = null;
	private $inerror = false;
	private $backtrace = array();
	private $raise_exception = false;

	public static $messagecode = array(
				500 => "Internal server error",
				204 => "No Content",
				404 => "Path not found",
				400 => "Bad Request",
				401 => "Unauthorized",
				417 => "Expectation failed",
	);


	protected function __construct() {
		error_reporting(E_ALL ^ (E_NOTICE | E_USER_NOTICE | (DEBUG ? 0 : (E_WARNING | E_USER_WARNING))));
		ini_set("display_errors", DEBUG ? 1 : 0);
		ini_set("track_errors", 1);
		ini_set("html_errors", 1);
		set_error_handler(array($this, "errorHandler"));
		set_exception_handler(array($this, "exceptionHandler"));
		register_shutdown_function(array($this, "checkForFatal"));
	}


	public static function unregister() {
		restore_error_handler();
		restore_exception_handler();
	}


	public static function Init($className) {
		if (is_null(self::$instance)) {
			self::$instance = new $className();
		}
	}


	public static function getInstance() {
		if (is_null(self::$instance)) {
			self::$instance = new self();
		}

		return self::$instance;
	}


	public static function RaiseExceptionOnError() {
		$i = self::getInstance();
		$i->raise_exception = true;
	}


	protected function addBacktrace($filename, $lineno, $class = null, $function = null, $args = null) {
		$this->backtrace[] = array($filename, $lineno, $class, $function, $args);
	}


	protected function formatErrorBody($code, $message, $body, $backtrace = array(), $log = array()) {
		$baseline = CorePlugin::getBaseline();
		if ($message === null) {
			if (isset(self::$messagecode[$code]))
				$message = self::$messagecode[$code];
			else
				$message = "Error #${code}";
		}

		 if (!DEBUG) {
			$body = "";
			$backtrace = array();
		}

		if (Template::findTemplate(ERROR_TEMPLATE) && !IS_CLI) {
			$tpt = new TemplateRes(array(
				"code" => $code,
				"message" => $message,
				"body" => $body,
				"debug" => ob_get_contents(),
				"backtrace" => $backtrace,
				"baseline" => $baseline,
				"log" => $log
			));
			header("Content-type: text/html");
			$tpt->output(ERROR_TEMPLATE);
		}
		header("Content-type: text/plain");
		$body = "$message ($code)\n$body";
		if (is_array($backtrace) && count($backtrace) > 0) {
			$body .= "\n\nBacktrace:\n";
			foreach($backtrace as $n => $bt) {
				$body .=
				"#$n"
				. " ${bt[0]} (${bt[1]}):\n"
				. (isset($bt[2]) ? $bt[2] . '->' : '')
				. (isset($bt[3]) ? $bt[3] . '(' . implode(', ', $bt[4]) . ')' : '')
				. "\n";
			}
		}
		$body .= "\n---\n" . $baseline . "\n";
		echo $body;
		Output::finish($code);
	}


	public static function error($code, $message = null, $body = null, $backtrace = 2, $finish = null) {
		$i = self::getInstance();
		if ($finish !== null)
			$i->raise_exception = !$finish;
		$i->send_error($code, $message, $body, $backtrace);
	}


	public function send_error($code, $message = null, $body = null, $backtrace = 1) {
		if ($this->inerror) {
			Logger::critical("Already processing error (send_error) $code $message $body");
			return;
		}

		$this->inerror = true;
		$protocol = (isset($_SERVER['SERVER_PROTOCOL']) ? $_SERVER['SERVER_PROTOCOL'] : 'HTTP/1.0');

		if ($message == null) {
			if (isset(self::$messagecode[$code]))
				$message = self::$messagecode[$code];
			else
				$message = "Error #${code}";
		}

		if ($body === null)
			$body = $message;

		if ($code >= 500) {
			Logger::critical("[$code] $message: $body");
		} else {
			Logger::info("[$code] $message: $body");
		}

		if ($this->raise_exception) {
			$this->inerror = false;
			throw new Exception($body);
		}

		header("$protocol $code $message");

		if ($code < 500 && $code != 404) {
			echo $body;
			Output::finish($code);
		}

		IS_CLI && Output::finish($code);

		if ($backtrace !== false) {
			$this->debugBacktrace($backtrace);
		}

		$this->formatErrorBody($code, $message, $body, $this->backtrace, array_slice(Logger::getInstance()->getLog(), 0, -1));
	}


	public function errorHandler($errno, $errstr, $errfile, $errline) {
		if ($this->inerror) {
			Logger::critical("Already processing error (error_handler) $errno, $errstr, $errfile, $errline");
			return;
		}
<commit_msg>Add newline if error in debug mode<commit_after><?php namespace DavBfr\CF;
/**
 * Copyright (C) 2013-2015 <NAME>
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
 **/

use Exception;

class ErrorHandler {
	private static $instance = null;
	private $inerror = false;
	private $backtrace = array();
	private $raise_exception = false;

	public static $messagecode = array(
				500 => "Internal server error",
				204 => "No Content",
				404 => "Path not found",
				400 => "Bad Request",
				401 => "Unauthorized",
				417 => "Expectation failed",
	);


	protected function __construct() {
		error_reporting(E_ALL ^ (E_NOTICE | E_USER_NOTICE | (DEBUG ? 0 : (E_WARNING | E_USER_WARNING))));
		ini_set("display_errors", DEBUG ? 1 : 0);
		ini_set("track_errors", 1);
		ini_set("html_errors", 1);
		set_error_handler(array($this, "errorHandler"));
		set_exception_handler(array($this, "exceptionHandler"));
		register_shutdown_function(array($this, "checkForFatal"));
	}


	public static function unregister() {
		restore_error_handler();
		restore_exception_handler();
	}


	public static function Init($className) {
		if (is_null(self::$instance)) {
			self::$instance = new $className();
		}
	}


	public static function getInstance() {
		if (is_null(self::$instance)) {
			self::$instance = new self();
		}

		return self::$instance;
	}


	public static function RaiseExceptionOnError() {
		$i = self::getInstance();
		$i->raise_exception = true;
	}


	protected function addBacktrace($filename, $lineno, $class = null, $function = null, $args = null) {
		$this->backtrace[] = array($filename, $lineno, $class, $function, $args);
	}


	protected function formatErrorBody($code, $message, $body, $backtrace = array(), $log = array()) {
		$baseline = CorePlugin::getBaseline();
		if ($message === null) {
			if (isset(self::$messagecode[$code]))
				$message = self::$messagecode[$code];
			else
				$message = "Error #${code}";
		}

		 if (!DEBUG) {
			$body = "";
			$backtrace = array();
		}

		if (Template::findTemplate(ERROR_TEMPLATE) && !IS_CLI) {
			$tpt = new TemplateRes(array(
				"code" => $code,
				"message" => $message,
				"body" => $body,
				"debug" => ob_get_contents(),
				"backtrace" => $backtrace,
				"baseline" => $baseline,
				"log" => $log
			));
			header("Content-type: text/html");
			$tpt->output(ERROR_TEMPLATE);
		}
		header("Content-type: text/plain");
		$body = "$message ($code)\n$body";
		if (is_array($backtrace) && count($backtrace) > 0) {
			$body .= "\n\nBacktrace:\n";
			foreach($backtrace as $n => $bt) {
				$body .=
				"#$n"
				. " ${bt[0]} (${bt[1]}):\n"
				. (isset($bt[2]) ? $bt[2] . '->' : '')
				. (isset($bt[3]) ? $bt[3] . '(' . implode(', ', $bt[4]) . ')' : '')
				. "\n";
			}
		}
		$body .= "\n---\n" . $baseline . "\n";
		echo $body;
		Output::finish($code);
	}


	public static function error($code, $message = null, $body = null, $backtrace = 2, $finish = null) {
		$i = self::getInstance();
		if ($finish !== null)
			$i->raise_exception = !$finish;
		$i->send_error($code, $message, $body, $backtrace);
	}


	public function send_error($code, $message = null, $body = null, $backtrace = 1) {
		if ($this->inerror) {
			Logger::critical("Already processing error (send_error) $code $message $body");
			return;
		}

		$this->inerror = true;
		$protocol = (isset($_SERVER['SERVER_PROTOCOL']) ? $_SERVER['SERVER_PROTOCOL'] : 'HTTP/1.0');

		if ($message == null) {
			if (isset(self::$messagecode[$code]))
				$message = self::$messagecode[$code];
			else
				$message = "Error #${code}";
		}

		if ($body === null)
			$body = $message;

		if ($code >= 500) {
			Logger::critical("[$code] $message: $body");
		} else {
			Logger::info("[$code] $message: $body");
		}

		if ($this->raise_exception) {
			$this->inerror = false;
			throw new Exception($body);
		}

		header("$protocol $code $message");

		if ($code < 500 && $code != 404) {
			echo $body;
			if (DEBUG)
				echo "\n";
			Output::finish($code);
		}

		IS_CLI && Output::finish($code);

		if ($backtrace !== false) {
			$this->debugBacktrace($backtrace);
		}

		$this->formatErrorBody($code, $message, $body, $this->backtrace, array_slice(Logger::getInstance()->getLog(), 0, -1));
	}


	public function errorHandler($errno, $errstr, $errfile, $errline) {
		if ($this->inerror) {
			Logger::critical("Already processing error (error_handler) $errno, $errstr, $errfile, $errline");
			return;
		}

{'fraction_non_alphanumeric': 0.17921006091570052, 'fraction_numerical': 0.013165651404991157, 'mean_word_length': 3.8726663475347056, 'pattern_counts': {'":': 0, '<': 9, '<?xml version=': 0, '>': 67, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '2213307', 'n_tokens_mistral': 3873, 'n_tokens_neox': 3345, 'n_words': 894}