5fb269cc0a
- 保存先写本地缓存,登录后可选云端同步;退出登录不再因文件操作跳转登录 - 修复 Layui 遮罩残留、design2 保存后线条、toast 被 finally 提前关闭 - 保存过程恢复 loading spinner;成功提示 2.5 秒 - 云端 payload 瘦身与体积超限提示;后端 schema 迁移与 FileService 容错 Co-authored-by: Cursor <cursoragent@cursor.com>
54 lines
1.7 KiB
PHP
54 lines
1.7 KiB
PHP
<?php
|
|
declare(strict_types=1);
|
|
|
|
namespace Soon\Api\Core;
|
|
|
|
use PDOException;
|
|
use Throwable;
|
|
|
|
/**
|
|
* API 未捕获异常 → JSON 响应(避免空白 500)。
|
|
*/
|
|
final class ErrorHandler
|
|
{
|
|
public static function register(): void
|
|
{
|
|
set_exception_handler([self::class, 'handleException']);
|
|
}
|
|
|
|
public static function handleException(Throwable $e): void
|
|
{
|
|
$path = parse_url($_SERVER['REQUEST_URI'] ?? '/', PHP_URL_PATH) ?: '/';
|
|
if (!str_starts_with($path, '/api/')) {
|
|
http_response_code(500);
|
|
exit;
|
|
}
|
|
$debug = (bool)Config::get('app.debug', false);
|
|
$code = 'server_error';
|
|
$msg = '服务器错误,请稍后重试';
|
|
$status = 500;
|
|
|
|
if ($e instanceof PDOException) {
|
|
$msg = '数据库操作失败';
|
|
$sqlState = (string)$e->getCode();
|
|
$detail = $e->getMessage();
|
|
if (str_contains($detail, 'max_allowed_packet') || str_contains($detail, 'Packet too large')) {
|
|
$code = 'payload_too_large';
|
|
$msg = '文件过大,超出服务器数据库限制';
|
|
$status = 413;
|
|
} elseif (str_contains($detail, 'Unknown column') || str_contains($detail, "doesn't exist")) {
|
|
$msg = '数据库结构不完整,请导入 database/schema.sql 或执行 php scripts/migrate-schema.php';
|
|
} elseif ($sqlState === '22001' || str_contains($detail, 'Data too long')) {
|
|
$code = 'payload_too_large';
|
|
$msg = '文件内容过长,无法保存';
|
|
$status = 413;
|
|
}
|
|
}
|
|
|
|
if ($debug) {
|
|
$msg .= ' (' . $e->getMessage() . ')';
|
|
}
|
|
Json::fail($code, $msg, $status);
|
|
}
|
|
}
|