ASP Error
ASPError 对象的九个属性、自定义错误页、错误捕获与日志。
九个属性
| Property | Meaning |
|---|---|
ASPCode | IIS 产生的错误码 |
Number | HRESULT,如 -2147467259 |
Source | 产生错误的对象或组件 |
Category | 错误来源分类 |
File | 出错的文件路径 |
Line | 出错的行 |
Column | 出错的列 |
Description | 错误说明 |
ASPDescription | 更详细的 ASP 层说明 |
自定义错误页
<%-- error.asp:IIS 里把 500.100 指向这个页面 --%>
<%@ Language="VBScript" CodePage="65001" %>
<%
Dim e
Set e = Server.GetLastError()
%>
<!DOCTYPE html>
<html><body>
<h1>出错了</h1>
<p>错误号:<%= e.ASPCode %></p>
<p>文件:<%= e.File %></p>
<p>行号:<%= e.Line %></p>
<%
' 详细信息只写日志,不显示给用户
Dim fso, log
Set fso = Server.CreateObject("Scripting.FileSystemObject")
Set log = fso.OpenTextFile(Server.MapPath("/logs/error.log"), 8, True)
log.WriteLine Now() & " | " & e.File & ":" & e.Line & " | " & e.Description
log.Close
Set log = Nothing
Set fso = Nothing
%>
</body></html>IIS 管理器 → 网站 → 错误页 → 编辑功能设置
☑ 自定义错误页
500.100 → URL: /error.aspServer.GetLastError() returns an ASPError only when IIS invokes the page as an error handler. Called from a normal page it returns Nothing, so e.ASPCode fails with "object not set".
页内错误捕获
<%
On Error Resume Next
Dim conn
Set conn = Server.CreateObject("ADODB.Connection")
conn.Open "Provider=SQLOLEDB;Data Source=db;..."
If Err.Number <> 0 Then
' 记录并给用户一个友好提示
Response.Write "数据库暂时不可用,请稍后再试。"
' 详细错误进日志
Response.Write "<!-- err " & Err.Number & ": " & Err.Description & " -->"
Err.Clear
End If
On Error GoTo 0
%>On Error Resume Next continues after an error and stores it in the Err object. Call Err.Clear after checking or later checks read a stale error.
On Error Resume Next is a disaster: one error is swallowed, the rest runs in a broken state, and the symptom is "the page looks fine but nothing was saved". Enable it around specific lines and immediately On Error GoTo 0.错误页不能泄露什么
<%-- 危险:把内部信息全暴露 --%>
<p><%= e.File %></p>
<p><%= e.Description %></p>
<p><%= e.Source %></p>- 物理路径 —— 暴露服务器目录结构,方便攻击者找上传点
- SQL 语句 —— ADO 的错误描述里常带完整 SQL
- 组件版本 —— 帮助攻击者匹配已知漏洞
IIS 的两个开关
ASP → 调试属性
☐ 将错误发送到浏览器 ← 生产环境必须关
☐ 启用详细 ASP 错误消息 ← 生产环境必须关With these on, IIS renders error details straight to the browser and skips your custom page. Handy in development, equivalent to publishing your source structure in production.
九个属性
| 属性 | 含义 |
|---|---|
| ASP 错误码 | IIS 产生的错误码 |
| COM 错误号 | HRESULT,如 -2147467259 |
| 来源 | 产生错误的对象或组件 |
| 类别 | 错误来源分类 |
| 文件 | 出错的文件路径 |
| 行号 | 出错的行 |
| 列号 | 出错的列 |
| 描述 | 错误说明 |
| ASP 描述 | 更详细的 ASP 层说明 |
自定义错误页
<%-- error.asp:IIS 里把 500.100 指向这个页面 --%>
<%@ Language="VBScript" CodePage="65001" %>
<%
Dim e
Set e = Server.GetLastError()
%>
<!DOCTYPE html>
<html><body>
<h1>出错了</h1>
<p>错误号:<%= e.ASPCode %></p>
<p>文件:<%= e.File %></p>
<p>行号:<%= e.Line %></p>
<%
' 详细信息只写日志,不显示给用户
Dim fso, log
Set fso = Server.CreateObject("Scripting.FileSystemObject")
Set log = fso.OpenTextFile(Server.MapPath("/logs/error.log"), 8, True)
log.WriteLine Now() & " | " & e.File & ":" & e.Line & " | " & e.Description
log.Close
Set log = Nothing
Set fso = Nothing
%>
</body></html>IIS 管理器 → 网站 → 错误页 → 编辑功能设置
☑ 自定义错误页
500.100 → URL: /error.aspServer.GetLastError() 只有在 IIS 把它当成错误处理页调用时才返回 ASPError 对象。普通页面里调用返回 Nothing,所以 e.ASPCode 会报「对象未设置」。
页内错误捕获
<%
On Error Resume Next
Dim conn
Set conn = Server.CreateObject("ADODB.Connection")
conn.Open "Provider=SQLOLEDB;Data Source=db;..."
If Err.Number <> 0 Then
' 记录并给用户一个友好提示
Response.Write "数据库暂时不可用,请稍后再试。"
' 详细错误进日志
Response.Write "<!-- err " & Err.Number & ": " & Err.Description & " -->"
Err.Clear
End If
On Error GoTo 0
%>On Error Resume Next 让出错后继续执行下一条语句,错误信息存进 Err 对象。检查完记得 Err.Clear,否则后面的判断会读到旧错误。
On Error Resume Next 加在整个页面上是灾难:一个错误被吞掉,后续代码在错误状态下继续跑,最后表现为「页面显示正常但数据没写进去」。只在明确要处理的几行前后开启,用完立刻 On Error GoTo 0。错误页不能泄露什么
<%-- 危险:把内部信息全暴露 --%>
<p><%= e.File %></p>
<p><%= e.Description %></p>
<p><%= e.Source %></p>- 物理路径 —— 暴露服务器目录结构,方便攻击者找上传点
- SQL 语句 —— ADO 的错误描述里常带完整 SQL
- 组件版本 —— 帮助攻击者匹配已知漏洞
IIS 的两个开关
ASP → 调试属性
☐ 将错误发送到浏览器 ← 生产环境必须关
☐ 启用详细 ASP 错误消息 ← 生产环境必须关这两个开关打开时,IIS 会把错误详情直接渲染到浏览器,连自定义错误页都不走。开发期方便,生产期等于把源码结构公开。