- Add CloudronStack/output/CloudronPackages-Artifacts/tirreno/ directory and its contents - Includes package manifest, Dockerfile, source code, documentation, and build artifacts - Add tirreno-1761840148.tar.gz as a build artifact - Add tirreno-cloudron-package-1761841304.tar.gz as the Cloudron package - Include all necessary files for the tirreno Cloudron package This adds the complete tirreno Cloudron package artifacts to the repository.
179 lines
5.9 KiB
PHP
179 lines
5.9 KiB
PHP
<?php
|
|
|
|
/**
|
|
* Tirreno ~ Open source user analytics
|
|
* Copyright (c) Tirreno Technologies Sàrl (https://www.tirreno.com)
|
|
*
|
|
* Licensed under GNU Affero General Public License version 3 of the or any later version.
|
|
* For full copyright and license information, please see the LICENSE
|
|
* Redistributions of files must retain the above copyright notice.
|
|
*
|
|
* @copyright Copyright (c) Tirreno Technologies Sàrl (https://www.tirreno.com)
|
|
* @license https://opensource.org/licenses/AGPL-3.0 AGPL License
|
|
* @link https://www.tirreno.com Tirreno(tm)
|
|
*/
|
|
|
|
namespace Utils;
|
|
|
|
class ErrorHandler {
|
|
public static function getErrorDetails(\Base $f3): array {
|
|
$errorTraceArray = [];
|
|
|
|
$errorTraceString = $f3->get('ERROR.trace');
|
|
$errorTraceArray = preg_split('/$\R?^/m', $errorTraceString);
|
|
$maximalStringIndex = 0;
|
|
$maximalStringLength = 0;
|
|
$iters = count($errorTraceArray);
|
|
|
|
for ($i = 0; $i < $iters; ++$i) {
|
|
$currentStringLength = strlen($errorTraceArray[$i]);
|
|
if ($maximalStringLength < $currentStringLength) {
|
|
$maximalStringIndex = $i;
|
|
$maximalStringLength = $currentStringLength;
|
|
}
|
|
}
|
|
|
|
if ($iters > 1) {
|
|
array_splice($errorTraceArray, $maximalStringIndex, 1);
|
|
}
|
|
|
|
$iters = count($errorTraceArray);
|
|
for ($i = 0; $i < $iters; ++$i) {
|
|
$errorTraceArray[$i] = strip_tags($errorTraceArray[$i]);
|
|
$errorTraceArray[$i] = str_replace(['>', '<'], ['>', '<'], $errorTraceArray[$i]);
|
|
}
|
|
|
|
$errorCode = $f3->get('ERROR.code');
|
|
$errorMessage = join(', ', ['ERROR_' . $errorCode, $f3->get('ERROR.text')]);
|
|
|
|
return [
|
|
'ip' => $f3->IP,
|
|
'code' => $errorCode,
|
|
'message' => $errorMessage,
|
|
'trace' => join('<br>', $errorTraceArray),
|
|
'date' => date('l jS \of F Y h:i:s A'),
|
|
'post' => $f3->get('POST'),
|
|
'get' => $f3->get('GET'),
|
|
];
|
|
}
|
|
|
|
public static function saveErrorInformation(\Base $f3, array $errorData): void {
|
|
\Utils\Logger::log(null, $errorData['message']);
|
|
|
|
$errorTraceArray = explode('<br>', $errorData['trace']);
|
|
$printErrorTraceToLog = $f3->get('PRINT_ERROR_TRACE_TO_LOG');
|
|
if ($printErrorTraceToLog) {
|
|
$iters = count($errorTraceArray);
|
|
|
|
for ($i = 0; $i < $iters; ++$i) {
|
|
\Utils\Logger::log(null, $errorTraceArray[$i]);
|
|
}
|
|
}
|
|
|
|
$db = $f3->get('API_DATABASE');
|
|
if ($db) {
|
|
$errorData['sql_log'] = $db->log();
|
|
$logModel = new \Models\Log();
|
|
$logModel->add($errorData);
|
|
|
|
\Utils\Logger::log('SQL', $errorData['sql_log']);
|
|
}
|
|
|
|
if ($errorData['code'] === 500) {
|
|
$toName = 'Admin';
|
|
$toAddress = \Utils\Variables::getAdminEmail();
|
|
if ($toAddress === null) {
|
|
\Utils\Logger::log('Log mail error', 'ADMIN_EMAIL is not set');
|
|
|
|
return;
|
|
}
|
|
|
|
$subject = $f3->get('error_email_subject');
|
|
$subject = sprintf($subject, $errorData['code']);
|
|
|
|
$currentTime = date('d-m-Y H:i:s');
|
|
$errorMessage = $errorData['message'];
|
|
$errorTrace = $errorData['trace'];
|
|
|
|
$message = $f3->get('error_email_body_template');
|
|
$message = sprintf($message, $currentTime, $errorMessage, $errorTrace);
|
|
|
|
\Utils\Mailer::send($toName, $toAddress, $subject, $message);
|
|
}
|
|
}
|
|
|
|
protected static function getAjaxErrorMessage(array $errorData): string|false {
|
|
return json_encode(
|
|
[
|
|
'status' => false,
|
|
'code' => $errorData['code'],
|
|
'message' => sprintf('Request finished with code %s', $errorData['code']),
|
|
],
|
|
);
|
|
}
|
|
|
|
public static function getOnErrorHandler(): callable {
|
|
/**
|
|
* Custom onError handler: http://stackoverflow.com/questions/19763414/fat-free-framework-f3-custom-404-page-and-others-errors, https://groups.google.com/forum/#!topic/f3-framework/BOIrLs5_aEA
|
|
* We can can use $f3->get('ERROR.text'), and decide which template should be displayed.
|
|
*
|
|
* @param $f3
|
|
*/
|
|
return function (\Base $f3): void {
|
|
$hive = $f3->hive();
|
|
$isAjax = $hive['AJAX'];
|
|
|
|
$errorData = self::getErrorDetails($f3);
|
|
self::saveErrorInformation($f3, $errorData);
|
|
|
|
if ($errorData['code'] === 403 && $isAjax) {
|
|
echo self::getAjaxErrorMessage($errorData);
|
|
|
|
return;
|
|
}
|
|
|
|
if ($errorData['code'] === 403 && !$isAjax) {
|
|
$f3->reroute('/logout');
|
|
|
|
return;
|
|
}
|
|
|
|
// Add handling 404 error
|
|
if ($errorData['code'] === 404) {
|
|
}
|
|
|
|
if ($isAjax) {
|
|
echo self::getAjaxErrorMessage($errorData);
|
|
|
|
return;
|
|
}
|
|
|
|
$response = new \Views\Frontend();
|
|
$pageController = new \Controllers\Pages\Error();
|
|
|
|
$errorData['message'] = 'ERROR_' . $errorData['code'];
|
|
unset($errorData['trace']);
|
|
$pageParams = $pageController->getPageParams($errorData);
|
|
|
|
$response->data = $pageParams;
|
|
echo $response->render();
|
|
};
|
|
}
|
|
|
|
public static function getCronErrorHandler(): callable {
|
|
return function (\Base $f3): void {
|
|
$errorData = self::getErrorDetails($f3);
|
|
self::saveErrorInformation($f3, $errorData);
|
|
};
|
|
}
|
|
|
|
public static function exceptionErrorHandler(int $severity, string $message, string $file, int $line): bool {
|
|
if (!(error_reporting() & $severity)) {
|
|
return false;
|
|
}
|
|
throw new \ErrorException($message, 0, $severity, $file, $line);
|
|
|
|
return true;
|
|
}
|
|
}
|