<commit_before><?php

class CM_ExceptionHandling_Handler {

	/**
	 * @param int $code
	 * @param string $message
	 * @param string $file
	 * @param int $line
	 * @return bool
	 * @throws ErrorException
	 */
	public function handleErrorRaw($code, $message, $file, $line) {
		$errorCodes = array(
			E_ERROR             => 'E_ERROR',
			E_WARNING           => 'E_WARNING',
			E_PARSE             => 'E_PARSE',
			E_NOTICE            => 'E_NOTICE',
			E_CORE_ERROR        => 'E_CORE_ERROR',
			E_CORE_WARNING      => 'E_CORE_WARNING',
			E_COMPILE_ERROR     => 'E_COMPILE_ERROR',
			E_COMPILE_WARNING   => 'E_COMPILE_WARNING',
			E_USER_ERROR        => 'E_USER_ERROR',
			E_USER_WARNING      => 'E_USER_WARNING',
			E_USER_NOTICE       => 'E_USER_NOTICE',
			E_STRICT            => 'E_STRICT',
			E_RECOVERABLE_ERROR => 'E_RECOVERABLE_ERROR',
			E_DEPRECATED        => 'E_DEPRECATED',
			E_USER_DEPRECATED   => 'E_USER_DEPRECATED',
			E_ALL               => 'E_ALL',
		);
		$message = $errorCodes[$code] . ': ' . $message;
		if (!(error_reporting() & $code)) {
			// This error code is not included in error_reporting
			$atSign = (0 === error_reporting()); // http://php.net/manual/en/function.set-error-handler.php
			if ($atSign) {
				return true;
			}
		}
		throw new ErrorException($message, 0, $code, $file, $line);
	}

	/**
	 * @param Exception                      $exception
	 * @param CM_OutputStream_Interface|null $output
	 */
	public function handleException(Exception $exception, CM_OutputStream_Interface $output = null) {
		$this->_logException($exception);
		$this->_printException($exception, $output);
	}

	/**
	 * @param Exception $exception
	 */
	private function _logException(Exception $exception) {
		$formatter = new CM_ExceptionHandling_Formatter_Plain();
		try {
			if ($exception instanceof CM_Exception) {
				$log = $exception->getLog();
			} else {
				$log = new CM_Paging_Log_Error();
			}
			$log->add($formatter->formatException($exception));
		} catch (Exception $loggerException) {
			$logEntry = '[' . date('d.m.Y - H:i:s', time()) . ']' . PHP_EOL;
			$logEntry .= '### Cannot log error: ' . PHP_EOL;
			$logEntry .= $formatter->formatException($loggerException);
			$logEntry .= '### Original Exception: ' . PHP_EOL;
			$logEntry .= $formatter->formatException($exception) . PHP_EOL;
			file_put_contents(DIR_DATA_LOG . 'error.log', $logEntry, FILE_APPEND);
		}
	}

	/**
	 * @param Exception                $exception
	 * @param CM_OutputStream_Abstract $output
	 */
	private function _printException(Exception $exception, CM_OutputStream_Abstract $output = null) {
		if (null === $output) {
			$output = new CM_OutputStream_Stream_Output();
		}
		if (!CM_Bootloader::getInstance()->isEnvironment('cli') && !CM_Bootloader::getInstance()->isEnvironment('test')) {
			header('HTTP/1.1 500 Internal Server Error');
		}


		$formatter = new CM_ExceptionHandling_Formatter_Plain();
		$isHttpRequest = !CM_Bootloader::getInstance()->isEnvironment('cli') && !CM_Bootloader::getInstance()->isEnvironment('test');
		if ($isHttpRequest) {
			if (!headers_sent()) {
				header('Content-Type: text/html');
			}
			$formatter = new CM_ExceptionHandling_Formatter_Html();<commit_msg>Allow pass of formatter to handle/_printException methods, simplify _printException logic<commit_after><?php

class CM_ExceptionHandling_Handler {

	/**
	 * @param int    $code
	 * @param string $message
	 * @param string $file
	 * @param int    $line
	 * @return bool
	 * @throws ErrorException
	 */
	public function handleErrorRaw($code, $message, $file, $line) {
		$errorCodes = array(
			E_ERROR             => 'E_ERROR',
			E_WARNING           => 'E_WARNING',
			E_PARSE             => 'E_PARSE',
			E_NOTICE            => 'E_NOTICE',
			E_CORE_ERROR        => 'E_CORE_ERROR',
			E_CORE_WARNING      => 'E_CORE_WARNING',
			E_COMPILE_ERROR     => 'E_COMPILE_ERROR',
			E_COMPILE_WARNING   => 'E_COMPILE_WARNING',
			E_USER_ERROR        => 'E_USER_ERROR',
			E_USER_WARNING      => 'E_USER_WARNING',
			E_USER_NOTICE       => 'E_USER_NOTICE',
			E_STRICT            => 'E_STRICT',
			E_RECOVERABLE_ERROR => 'E_RECOVERABLE_ERROR',
			E_DEPRECATED        => 'E_DEPRECATED',
			E_USER_DEPRECATED   => 'E_USER_DEPRECATED',
			E_ALL               => 'E_ALL',
		);
		$message = $errorCodes[$code] . ': ' . $message;
		if (!(error_reporting() & $code)) {
			// This error code is not included in error_reporting
			$atSign = (0 === error_reporting()); // http://php.net/manual/en/function.set-error-handler.php
			if ($atSign) {
				return true;
			}
		}
		throw new ErrorException($message, 0, $code, $file, $line);
	}

	/**
	 * @param Exception                                    $exception
	 * @param CM_OutputStream_Interface|null               $output
	 * @param CM_ExceptionHandling_Formatter_Abstract|null $formatter
	 */
	public function handleException(Exception $exception, CM_OutputStream_Interface $output = null, CM_ExceptionHandling_Formatter_Abstract $formatter = null) {
		$this->_logException($exception);
		$this->_printException($exception, $output, $formatter);
	}

	/**
	 * @param Exception $exception
	 */
	private function _logException(Exception $exception) {
		$formatter = new CM_ExceptionHandling_Formatter_Plain();
		try {
			if ($exception instanceof CM_Exception) {
				$log = $exception->getLog();
			} else {
				$log = new CM_Paging_Log_Error();
			}
			$log->add($formatter->formatException($exception));
		} catch (Exception $loggerException) {
			$logEntry = '[' . date('d.m.Y - H:i:s', time()) . ']' . PHP_EOL;
			$logEntry .= '### Cannot log error: ' . PHP_EOL;
			$logEntry .= $formatter->formatException($loggerException);
			$logEntry .= '### Original Exception: ' . PHP_EOL;
			$logEntry .= $formatter->formatException($exception) . PHP_EOL;
			file_put_contents(DIR_DATA_LOG . 'error.log', $logEntry, FILE_APPEND);
		}
	}

	/**
	 * @param Exception                                    $exception
	 * @param CM_OutputStream_Abstract|null                $output
	 * @param CM_ExceptionHandling_Formatter_Abstract|null $formatter
	 */
	private function _printException(Exception $exception, CM_OutputStream_Abstract $output = null, CM_ExceptionHandling_Formatter_Abstract $formatter = null) {
		if (null === $output) {
			$output = new CM_OutputStream_Stream_Output();
		}

		$isHttpRequest = !CM_Bootloader::getInstance()->isEnvironment('cli') && !CM_Bootloader::getInstance()->isEnvironment('test');
		if ($isHttpRequest) {
			if (!headers_sent()) {
				header('HTTP/1.1 500 Internal Server Error');
				header('Content-Type: text/html');
			}
			if (null === $formatter) {
				$formatter = new CM_ExceptionHandling_Formatter_Html();
			}
		}
		if (null === $formatter) {
			$formatter = new CM_ExceptionHandling_Formatter_Plain();
{'fraction_non_alphanumeric': 0.1430258302583026, 'fraction_numerical': 0.002066420664206642, 'mean_word_length': 3.4200913242009134, 'pattern_counts': {'":': 0, '<': 5, '<?xml version=': 0, '>': 55, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 2, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '3420004', 'n_tokens_mistral': 2427, 'n_tokens_neox': 2138, 'n_words': 414}