Files
Krystie 092a8bc7ce refactor: organize codebase and remove redundant files
- 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
2026-03-30 16:34:45 -07:00

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
]));
}
}