Xiuno BBS 重构记录贴(六)错误页面与全局错误处理
贰先生 2小时前

# 错误页面与全局错误处理 Spec

## Why
Xiuno BBS 当前路由未命中时默认回退到首页(而非 404),`http_404()` / `http_403()` 仅输出纯文本 `<h1>` 标签,无全局异常捕获机制,生产环境可能暴露敏感错误信息。需要友好的错误页面和完善的错误处理。

## What Changes
- 创建 `lib/ErrorHandler.php`:注册自定义错误处理、异常处理、致命错误捕获,生产环境隐藏敏感信息
- 创建 `view/htm/error.htm`:通用错误模板,支持 404/403/500 三种类型,Bootstrap 5 + Tabler Icons
- 修改 `index.inc.php`:路由 default 分支调用 `error_page(404)` 替代回退首页
- 修改 `admin/index.inc.php`:路由 default 分支调用 `error_page(404)`
- 覆盖 `xiunophp/misc.func.php` 中的 `http_404()` / `http_403()` 函数,改为渲染错误模板
- 在 `index.php` 入口注册 ErrorHandler

## Impact
- Affected code: `index.php`, `index.inc.php`, `admin/index.inc.php`, `model/misc.func.php`
- New files: `lib/ErrorHandler.php`, `view/htm/error.htm`
- 不影响现有正常业务逻辑

## ADDED Requirements

### Requirement: 通用错误页面
系统 SHALL 提供统一的错误页面模板 `view/htm/error.htm`,通过参数区分错误类型(404/403/500),包含:
- 正确的 HTTP 状态码(`http_response_code()`)
- 友好提示文案
- Tabler Icons 图标(404: `ti-error-404`, 403: `ti-lock-access`, 500: `ti-server-bolt`)
- 返回首页按钮(`btn btn-primary rounded-pill`)
- 返回上一页按钮(`btn btn-outline-secondary rounded-pill`)
- 手机响应式布局
- 不依赖 jQuery

#### Scenario: 用户访问不存在的路由
- **WHEN** 用户访问未定义的路由路径
- **THEN** 返回 HTTP 404 状态码,显示友好的 404 错误页面

#### Scenario: 用户无权限访问
- **WHEN** 用户尝试访问无权限的资源
- **THEN** 返回 HTTP 403 状态码,显示友好的 403 错误页面

#### Scenario: 服务器内部错误
- **WHEN** 程序抛出未捕获异常或发生致命错误
- **THEN** 返回 HTTP 500 状态码,显示友好的 500 错误页面;生产环境不暴露错误详情

### Requirement: 全局错误处理
系统 SHALL 在入口文件注册 `ErrorHandler`,处理以下情况:
- `set_error_handler`:捕获 E_WARNING / E_NOTICE 等,生产环境不输出,开发环境显示调试信息
- `set_exception_handler`:捕获未处理异常,渲染 500 页面
- `register_shutdown_function`:捕获致命错误(E_ERROR),渲染 500 页面
- 生产环境(DEBUG=0):隐藏所有敏感信息,仅记录日志
- 开发环境(DEBUG>0):显示错误详情

#### Scenario: 生产环境数据库异常
- **WHEN** DEBUG=0 且数据库查询抛出异常
- **THEN** 返回 HTTP 500,页面仅显示"服务器内部错误",不暴露堆栈信息

#### Scenario: 开发环境程序错误
- **WHEN** DEBUG>0 且程序抛出异常
- **THEN** 返回 HTTP 500,页面显示错误详情(文件、行号、堆栈)

### Requirement: 路由 404 处理
系统 SHALL 在路由匹配失败时返回 404 页面而非回退到首页。

#### Scenario: 前台路由未命中
- **WHEN** 前台 `index.inc.php` 的 switch default 分支被触发
- **THEN** 调用 `error_page(404)` 显示 404 错误页面

#### Scenario: 后台路由未命中
- **WHEN** 后台 `admin/index.inc.php` 的 switch default 分支被触发
- **THEN** 调用 `error_page(404)` 显示 404 错误页面

## MODIFIED Requirements

### Requirement: http_404() / http_403() 函数行为
原函数仅输出纯文本 `<h1>` 标签。修改为渲染完整的错误页面模板,保持函数签名不变,确保向后兼容。

## REMOVED Requirements
无
最新回复 (0)
全部楼主
返回