092a8bc7ce
- Removed all backup/duplicate files - Removed test files from root - Consolidated documentation to /docs/ - Moved scripts to /scripts/ - Renamed f_* directories (removed prefix) - Organized icons and assets - Removed unused vendor directories - Cleaned up redundant config files
356 lines
11 KiB
PHP
356 lines
11 KiB
PHP
<?php
|
|
/*******************************************************************************************************************
|
|
| Software Name : EasyStream
|
|
| Software Description : High End YouTube Clone Script with Videos, Shorts, Streams, Images, Audio, Documents, Blogs
|
|
| Software Author : (c) Sami Ahmed
|
|
|*******************************************************************************************************************
|
|
|
|
|
|*******************************************************************************************************************
|
|
| This source file is subject to the EasyStream Proprietary License Agreement.
|
|
|
|
|
| By using this software, you acknowledge having read this Agreement and agree to be bound thereby.
|
|
|*******************************************************************************************************************
|
|
| Copyright (c) 2025 Sami Ahmed. All rights reserved.
|
|
|*******************************************************************************************************************/
|
|
|
|
defined('_ISVALID') or header('Location: /error');
|
|
|
|
/**
|
|
* Global Error Handler for comprehensive error tracking
|
|
*/
|
|
class VErrorHandler
|
|
{
|
|
private static $instance = null;
|
|
private $logger;
|
|
private $isProduction = true;
|
|
|
|
public static function getInstance()
|
|
{
|
|
if (self::$instance === null) {
|
|
self::$instance = new self();
|
|
}
|
|
return self::$instance;
|
|
}
|
|
|
|
private function __construct()
|
|
{
|
|
$this->logger = VLogger::getInstance();
|
|
|
|
// Determine if we're in production mode
|
|
global $cfg;
|
|
$this->isProduction = !isset($cfg['debug_mode']) || !$cfg['debug_mode'];
|
|
|
|
// Register error handlers
|
|
$this->registerHandlers();
|
|
}
|
|
|
|
/**
|
|
* Register all error handlers
|
|
*/
|
|
private function registerHandlers()
|
|
{
|
|
// Set error handler for PHP errors
|
|
set_error_handler([$this, 'handleError']);
|
|
|
|
// Set exception handler for uncaught exceptions
|
|
set_exception_handler([$this, 'handleException']);
|
|
|
|
// Set shutdown handler for fatal errors
|
|
register_shutdown_function([$this, 'handleShutdown']);
|
|
|
|
// Set error reporting level
|
|
if ($this->isProduction) {
|
|
error_reporting(E_ALL & ~E_NOTICE & ~E_DEPRECATED & ~E_STRICT);
|
|
ini_set('display_errors', 0);
|
|
ini_set('log_errors', 1);
|
|
} else {
|
|
error_reporting(E_ALL);
|
|
ini_set('display_errors', 1);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Handle PHP errors
|
|
*/
|
|
public function handleError($severity, $message, $file, $line, $context = [])
|
|
{
|
|
// Don't handle errors that are suppressed with @
|
|
if (!(error_reporting() & $severity)) {
|
|
return false;
|
|
}
|
|
|
|
$errorType = $this->getErrorType($severity);
|
|
$logLevel = $this->getLogLevel($severity);
|
|
|
|
$errorContext = [
|
|
'error_type' => $errorType,
|
|
'severity' => $severity,
|
|
'file' => $file,
|
|
'line' => $line,
|
|
'context' => $context
|
|
];
|
|
|
|
$errorMessage = "{$errorType}: {$message} in {$file} on line {$line}";
|
|
|
|
$this->logger->log($logLevel, $errorMessage, $errorContext);
|
|
|
|
// Don't execute PHP internal error handler
|
|
return true;
|
|
}
|
|
|
|
/**
|
|
* Handle uncaught exceptions
|
|
*/
|
|
public function handleException($exception)
|
|
{
|
|
$errorContext = [
|
|
'exception_class' => get_class($exception),
|
|
'file' => $exception->getFile(),
|
|
'line' => $exception->getLine(),
|
|
'trace' => $exception->getTraceAsString(),
|
|
'previous' => $exception->getPrevious() ? $exception->getPrevious()->getMessage() : null
|
|
];
|
|
|
|
$errorMessage = "Uncaught Exception: " . $exception->getMessage() .
|
|
" in " . $exception->getFile() . " on line " . $exception->getLine();
|
|
|
|
$this->logger->critical($errorMessage, $errorContext);
|
|
|
|
// Show user-friendly error page in production
|
|
if ($this->isProduction) {
|
|
$this->showErrorPage('An unexpected error occurred. Please try again later.');
|
|
} else {
|
|
$this->showDebugError($exception);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Handle fatal errors during shutdown
|
|
*/
|
|
public function handleShutdown()
|
|
{
|
|
$error = error_get_last();
|
|
|
|
if ($error && in_array($error['type'], [E_ERROR, E_PARSE, E_CORE_ERROR, E_COMPILE_ERROR])) {
|
|
$errorType = $this->getErrorType($error['type']);
|
|
|
|
$errorContext = [
|
|
'error_type' => $errorType,
|
|
'severity' => $error['type'],
|
|
'file' => $error['file'],
|
|
'line' => $error['line']
|
|
];
|
|
|
|
$errorMessage = "Fatal Error: {$error['message']} in {$error['file']} on line {$error['line']}";
|
|
|
|
$this->logger->critical($errorMessage, $errorContext);
|
|
|
|
// Show error page for fatal errors
|
|
if ($this->isProduction) {
|
|
$this->showErrorPage('A critical error occurred. Please contact support.');
|
|
}
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Get error type string from severity level
|
|
*/
|
|
private function getErrorType($severity)
|
|
{
|
|
$errorTypes = [
|
|
E_ERROR => 'Fatal Error',
|
|
E_WARNING => 'Warning',
|
|
E_PARSE => 'Parse Error',
|
|
E_NOTICE => 'Notice',
|
|
E_CORE_ERROR => 'Core Error',
|
|
E_CORE_WARNING => 'Core Warning',
|
|
E_COMPILE_ERROR => 'Compile Error',
|
|
E_COMPILE_WARNING => 'Compile Warning',
|
|
E_USER_ERROR => 'User Error',
|
|
E_USER_WARNING => 'User Warning',
|
|
E_USER_NOTICE => 'User Notice',
|
|
E_STRICT => 'Strict Standards',
|
|
E_RECOVERABLE_ERROR => 'Recoverable Error',
|
|
E_DEPRECATED => 'Deprecated',
|
|
E_USER_DEPRECATED => 'User Deprecated'
|
|
];
|
|
|
|
return $errorTypes[$severity] ?? 'Unknown Error';
|
|
}
|
|
|
|
/**
|
|
* Get log level from error severity
|
|
*/
|
|
private function getLogLevel($severity)
|
|
{
|
|
switch ($severity) {
|
|
case E_ERROR:
|
|
case E_PARSE:
|
|
case E_CORE_ERROR:
|
|
case E_COMPILE_ERROR:
|
|
case E_USER_ERROR:
|
|
case E_RECOVERABLE_ERROR:
|
|
return VLogger::ERROR;
|
|
|
|
case E_WARNING:
|
|
case E_CORE_WARNING:
|
|
case E_COMPILE_WARNING:
|
|
case E_USER_WARNING:
|
|
return VLogger::WARNING;
|
|
|
|
case E_NOTICE:
|
|
case E_USER_NOTICE:
|
|
case E_STRICT:
|
|
return VLogger::NOTICE;
|
|
|
|
case E_DEPRECATED:
|
|
case E_USER_DEPRECATED:
|
|
return VLogger::INFO;
|
|
|
|
default:
|
|
return VLogger::ERROR;
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Show user-friendly error page
|
|
*/
|
|
private function showErrorPage($message)
|
|
{
|
|
// Clear any output buffer
|
|
if (ob_get_level()) {
|
|
ob_clean();
|
|
}
|
|
|
|
http_response_code(500);
|
|
|
|
// Try to use existing error template
|
|
if (file_exists('error.php')) {
|
|
include 'error.php';
|
|
} else {
|
|
// Fallback error page
|
|
echo $this->getErrorPageHTML($message);
|
|
}
|
|
|
|
exit;
|
|
}
|
|
|
|
/**
|
|
* Show debug error information
|
|
*/
|
|
private function showDebugError($exception)
|
|
{
|
|
if (ob_get_level()) {
|
|
ob_clean();
|
|
}
|
|
|
|
http_response_code(500);
|
|
|
|
echo $this->getDebugErrorHTML($exception);
|
|
exit;
|
|
}
|
|
|
|
/**
|
|
* Get error page HTML
|
|
*/
|
|
private function getErrorPageHTML($message)
|
|
{
|
|
return '<!DOCTYPE html>
|
|
<html>
|
|
<head>
|
|
<title>Error - EasyStream</title>
|
|
<style>
|
|
body { font-family: Arial, sans-serif; margin: 40px; background: #f5f5f5; }
|
|
.error-container { background: white; padding: 30px; border-radius: 8px; box-shadow: 0 2px 10px rgba(0,0,0,0.1); max-width: 600px; margin: 0 auto; }
|
|
.error-title { color: #d32f2f; font-size: 24px; margin-bottom: 20px; }
|
|
.error-message { color: #666; line-height: 1.6; }
|
|
.error-actions { margin-top: 30px; }
|
|
.btn { background: #1976d2; color: white; padding: 10px 20px; text-decoration: none; border-radius: 4px; display: inline-block; }
|
|
.btn:hover { background: #1565c0; }
|
|
</style>
|
|
</head>
|
|
<body>
|
|
<div class="error-container">
|
|
<h1 class="error-title">Oops! Something went wrong</h1>
|
|
<p class="error-message">' . htmlspecialchars($message) . '</p>
|
|
<div class="error-actions">
|
|
<a href="/" class="btn">Go Home</a>
|
|
<a href="javascript:history.back()" class="btn" style="background: #666; margin-left: 10px;">Go Back</a>
|
|
</div>
|
|
</div>
|
|
</body>
|
|
</html>';
|
|
}
|
|
|
|
/**
|
|
* Get debug error HTML
|
|
*/
|
|
private function getDebugErrorHTML($exception)
|
|
{
|
|
$trace = $exception->getTraceAsString();
|
|
|
|
return '<!DOCTYPE html>
|
|
<html>
|
|
<head>
|
|
<title>Debug Error - EasyStream</title>
|
|
<style>
|
|
body { font-family: monospace; margin: 20px; background: #1e1e1e; color: #fff; }
|
|
.error-header { background: #d32f2f; padding: 15px; margin-bottom: 20px; border-radius: 4px; }
|
|
.error-details { background: #2d2d2d; padding: 15px; border-radius: 4px; margin-bottom: 20px; }
|
|
.trace { background: #1a1a1a; padding: 15px; border-radius: 4px; overflow-x: auto; }
|
|
pre { margin: 0; white-space: pre-wrap; }
|
|
.file-line { color: #ffeb3b; }
|
|
.message { color: #f44336; font-weight: bold; }
|
|
</style>
|
|
</head>
|
|
<body>
|
|
<div class="error-header">
|
|
<h1>Exception: ' . htmlspecialchars(get_class($exception)) . '</h1>
|
|
</div>
|
|
|
|
<div class="error-details">
|
|
<p><strong>Message:</strong> <span class="message">' . htmlspecialchars($exception->getMessage()) . '</span></p>
|
|
<p><strong>File:</strong> <span class="file-line">' . htmlspecialchars($exception->getFile()) . ':' . $exception->getLine() . '</span></p>
|
|
</div>
|
|
|
|
<div class="trace">
|
|
<h3>Stack Trace:</h3>
|
|
<pre>' . htmlspecialchars($trace) . '</pre>
|
|
</div>
|
|
</body>
|
|
</html>';
|
|
}
|
|
|
|
/**
|
|
* Log custom application errors
|
|
*/
|
|
public function logApplicationError($message, $context = [])
|
|
{
|
|
$this->logger->error('Application Error: ' . $message, $context);
|
|
}
|
|
|
|
/**
|
|
* Log validation errors
|
|
*/
|
|
public function logValidationError($field, $value, $rule, $context = [])
|
|
{
|
|
$message = "Validation failed for field '{$field}' with value '{$value}' against rule '{$rule}'";
|
|
$this->logger->warning($message, array_merge($context, [
|
|
'validation_error' => true,
|
|
'field' => $field,
|
|
'value' => $value,
|
|
'rule' => $rule
|
|
]));
|
|
}
|
|
|
|
/**
|
|
* Log authentication errors
|
|
*/
|
|
public function logAuthError($message, $username = null, $context = [])
|
|
{
|
|
$this->logger->warning('Authentication Error: ' . $message, array_merge($context, [
|
|
'auth_error' => true,
|
|
'username' => $username
|
|
]));
|
|
}
|
|
} |