ASP 3.0高级编程(三十)
程序员文章站
2022-06-22 11:26:43
第7章
调试和错误处理
前面已经介绍了使用asp所需要的基本技能,本章要讨论的...
第7章
调试和错误处理
前面已经介绍了使用asp所需要的基本技能,本章要讨论的另外一个问题是当asp出现错误时怎么办,asp出错时是什么情况。当精心编排的asp页面出现问题停止了执行时,用户一般得到的仅是一些用处不大的建议,诸如:点击“刷新”按钮,或者“与站点的web管理员联系,告诉他们你的页面不能正常工作了”等等。
本章除了提供有用的信息外,还想提供一个帮助区域。我们将详细介绍在脚本和页面中错误如何出现,可能产生的错误类型,以及什么造成了这些错误。更重要的是,要讨论如何尽可能避免错误的发生,如不能避免又如何妥善处理。
因此,本章将要探讨页面调试技术,也就是如何花费不多的精力和时间就能找到错误并解决问题。
本章包括以下内容:
· 能够出现的错误类型。
· 如何防止各种错误的产生。
· 如果不能防止错误发生,如何妥善处理这些错误。
· 如何发现和处理脚本错误及其他类型的错误。
· 如何使用定制的错误页面得到错误信息。
· 如何记录发生的错误以监视我们的网站。
· 创建一个定制错误网页和一个错误日志文件。
· 提供相关的在线帮助。
本章不涉及如何处理使用activex data objects(ado)访问数据源时出现的各种特殊类型的错误。像许多一样,ado提供了自己的错误处理,第8章将深入讨论这一点。本章将从讨论能出现的各种错误类型开始,使我们能够认识这些错误并采取相应的措施。
据说,在非洲最黑暗的雨林深处,有这样一群程序员,他们的程序代码从来没有出现过错误。但是,很遗憾他们从没有享受过调试一段不能正常工作的应用程序的乐趣。调试程序代码是一个真正充满快乐的工作,所以我们要面对这个问题,在调试程序的过程中检验我们的观察力和横向思维能力。大多数“真实世界”的程序员能够体验这些乐趣是一件好事。
当然,有些人会说,调试程序与其说是判断,不如说是碰运气。花费了许多时间去调试一段有错误的程序,在某种程度上可以说确实是依赖运气。但是,如果第一步从合适的地方开始查看,可能会更快地解决问题。
但这不是程序调试应采取的办法。从理论上讲,当某段程序运行失败时,应该以逻辑或顺序方式跟踪错误。作为一个聪明和有经验的程序员,这才是调试时常用的方法,只有业余人员才随意改变程序中变量的值,到处添加response.write语句进行调试。
然而,为了能够在逻辑上跟踪程序中的错误,必须了解有关错误如何出现方面的基础知识,更重要的是知道错误出现在哪里,以便很快就能找到相应的地方。本章讨论的内容是有关程序中能够出现的不同种类的错误,错误的不同表现,以及如何记录和排除这些错误。同样重要的是,还将介绍如何避免这些错误的发生。
本章将从介绍可能出现的不同种类的错误开始,如果认为你的代码不会出现任何错误,可以直接跳到下一章。
7.1 错误的种类
7.1.1 语法或“编译”错误
当我们第一次运行新编写的程序代码时,通常看到的第一种错误类型是“syntax error”。这就是所说的,程序代码上的语法错误。这就像在写作中使用了错误的语法,使读者不能了解其中的含义。而解释器(诸如脚本引擎)和编译器对语法要求得更加严格和准确。
语法错误通常也是最早出现和需要排除的。大多数情况下,解释器和编译器会指出行号和所在行中的字符位置,以及在相应的位置上缺少的内容。下面举一个简单的例子,如下所示的这样一段程序:
<%
response.write "the repayments for your loan are $" & chrpayment _
& " per " & strinterval & , due on the " &strday & " of each "
& strinterval & "."
%>
我们希望得到下面的结果:
the repayments for your loan are $124.50 per month, due on the 12th of each month.
实际上得到的结果如图7-1所示:
图7-1 程序执行结果1
豆豆注:
如果你的错误提示信息无法出现“语法错误”,请将你的winnthelpiishelpcommon500-100.做如下改变(加了两行黑体字):
...
dim bakcodepage
bakcodepage = session.codepage
session.codepage = 936
response.write server.htmlencode(objasperror.category)
if objasperror.aspcode > "" then response.write server.htmlencode(", " & objasperror.aspcode)
response.write server.htmlencode(" (0x" & hex(objasperror.number) & ")" ) & "<br>"
if objasperror.aspdescription > "" then response.write server.htmlencode(objasperror.aspdescription) & "<br>"
blnerrorwritten = false
response.write "<b>"
if objasperror.description > "" then response.write server.htmlencode(objasperror.description) & "<br>"
only show the source if it is available and the request is from the same machine as iis
…
文件中第3行是response.write语句的第2行。报告错误信息时,vbscript解释器忽略一行中的引导空格和制表符。所以在数完26个字符之后,可以找到语法错误的地方,这里明显缺少了一个双引号。加上双引号后再运行这个页面,我们可以得到如图7-2所示:
图7-2 程序执行结果2
这次又是另外一个简单错误。实际上错误出现在第3行而不是第4行。我们漏掉了第三行末尾的续行符_。程序代码应该是:
<%
response.write "the repayments for your loan are $" & chrpayment _
& " per " & strinterval & ", due on the " &strday & " of each " _
& strinterval & "."
%>
1. 错误出现在什么地方
需要注意的是脚本解释器仅指出所发现错误的地方,但实际上那儿并不一定是错误真正出现的地方。在上例中,前面三行的语法正确的;并产生相应的输出结果,而恰恰是第4行引起问题,因为这一行是以一种非法字符开头的,脚本解释器没有意识到这一行是上一行的一部分。
这样的错误是普遍存在的,因为通常我们主要考虑的是要输出的文本内容,而不是双引号、连字符(在vbscript中为“&”)、续行符等的正确顺序。
对于关键字、内部函数名拼写错误或函数的非法参数列表而引起的语法错误,通常比较容易发现,因为错误信息提示可能就指出了错误的实际位置。例如:下面这段代码是想把明天的日期写入页面。
response.write dateadd(now(),"d", 1)
实际得到的结果如图7-3所示:
图7-3 程序执行结果3
这是因为dateadd函数的语法应该是:
dateadd (interval_string, interval_number, start_date)
所以应该改写为如下的代码:
response.write dateadd("d", 1, now())
脚本解释器检测到了我们为第二个参数提供的是一个字符型数据,而dateadd函数需要的是整型数据类型。
代码结构和脚本结构
语法错误的另一个原因是:当制作网页时使用嵌套的或复杂的脚本结构,如if then … else … end if或者do while … loop。这有时会造成难以找到的语法错误。
例如下面这段程序:
<%
if len(request.form("cmdset")) then
strcountername = request.form("lstset")
strnewvalue = request.form("txtset")
调试和错误处理
前面已经介绍了使用asp所需要的基本技能,本章要讨论的另外一个问题是当asp出现错误时怎么办,asp出错时是什么情况。当精心编排的asp页面出现问题停止了执行时,用户一般得到的仅是一些用处不大的建议,诸如:点击“刷新”按钮,或者“与站点的web管理员联系,告诉他们你的页面不能正常工作了”等等。
本章除了提供有用的信息外,还想提供一个帮助区域。我们将详细介绍在脚本和页面中错误如何出现,可能产生的错误类型,以及什么造成了这些错误。更重要的是,要讨论如何尽可能避免错误的发生,如不能避免又如何妥善处理。
因此,本章将要探讨页面调试技术,也就是如何花费不多的精力和时间就能找到错误并解决问题。
本章包括以下内容:
· 能够出现的错误类型。
· 如何防止各种错误的产生。
· 如果不能防止错误发生,如何妥善处理这些错误。
· 如何发现和处理脚本错误及其他类型的错误。
· 如何使用定制的错误页面得到错误信息。
· 如何记录发生的错误以监视我们的网站。
· 创建一个定制错误网页和一个错误日志文件。
· 提供相关的在线帮助。
本章不涉及如何处理使用activex data objects(ado)访问数据源时出现的各种特殊类型的错误。像许多一样,ado提供了自己的错误处理,第8章将深入讨论这一点。本章将从讨论能出现的各种错误类型开始,使我们能够认识这些错误并采取相应的措施。
据说,在非洲最黑暗的雨林深处,有这样一群程序员,他们的程序代码从来没有出现过错误。但是,很遗憾他们从没有享受过调试一段不能正常工作的应用程序的乐趣。调试程序代码是一个真正充满快乐的工作,所以我们要面对这个问题,在调试程序的过程中检验我们的观察力和横向思维能力。大多数“真实世界”的程序员能够体验这些乐趣是一件好事。
当然,有些人会说,调试程序与其说是判断,不如说是碰运气。花费了许多时间去调试一段有错误的程序,在某种程度上可以说确实是依赖运气。但是,如果第一步从合适的地方开始查看,可能会更快地解决问题。
但这不是程序调试应采取的办法。从理论上讲,当某段程序运行失败时,应该以逻辑或顺序方式跟踪错误。作为一个聪明和有经验的程序员,这才是调试时常用的方法,只有业余人员才随意改变程序中变量的值,到处添加response.write语句进行调试。
然而,为了能够在逻辑上跟踪程序中的错误,必须了解有关错误如何出现方面的基础知识,更重要的是知道错误出现在哪里,以便很快就能找到相应的地方。本章讨论的内容是有关程序中能够出现的不同种类的错误,错误的不同表现,以及如何记录和排除这些错误。同样重要的是,还将介绍如何避免这些错误的发生。
本章将从介绍可能出现的不同种类的错误开始,如果认为你的代码不会出现任何错误,可以直接跳到下一章。
7.1 错误的种类
7.1.1 语法或“编译”错误
当我们第一次运行新编写的程序代码时,通常看到的第一种错误类型是“syntax error”。这就是所说的,程序代码上的语法错误。这就像在写作中使用了错误的语法,使读者不能了解其中的含义。而解释器(诸如脚本引擎)和编译器对语法要求得更加严格和准确。
语法错误通常也是最早出现和需要排除的。大多数情况下,解释器和编译器会指出行号和所在行中的字符位置,以及在相应的位置上缺少的内容。下面举一个简单的例子,如下所示的这样一段程序:
<%
response.write "the repayments for your loan are $" & chrpayment _
& " per " & strinterval & , due on the " &strday & " of each "
& strinterval & "."
%>
我们希望得到下面的结果:
the repayments for your loan are $124.50 per month, due on the 12th of each month.
实际上得到的结果如图7-1所示:
图7-1 程序执行结果1
豆豆注:
如果你的错误提示信息无法出现“语法错误”,请将你的winnthelpiishelpcommon500-100.做如下改变(加了两行黑体字):
...
dim bakcodepage
bakcodepage = session.codepage
session.codepage = 936
response.write server.htmlencode(objasperror.category)
if objasperror.aspcode > "" then response.write server.htmlencode(", " & objasperror.aspcode)
response.write server.htmlencode(" (0x" & hex(objasperror.number) & ")" ) & "<br>"
if objasperror.aspdescription > "" then response.write server.htmlencode(objasperror.aspdescription) & "<br>"
blnerrorwritten = false
response.write "<b>"
if objasperror.description > "" then response.write server.htmlencode(objasperror.description) & "<br>"
only show the source if it is available and the request is from the same machine as iis
…
文件中第3行是response.write语句的第2行。报告错误信息时,vbscript解释器忽略一行中的引导空格和制表符。所以在数完26个字符之后,可以找到语法错误的地方,这里明显缺少了一个双引号。加上双引号后再运行这个页面,我们可以得到如图7-2所示:
图7-2 程序执行结果2
这次又是另外一个简单错误。实际上错误出现在第3行而不是第4行。我们漏掉了第三行末尾的续行符_。程序代码应该是:
<%
response.write "the repayments for your loan are $" & chrpayment _
& " per " & strinterval & ", due on the " &strday & " of each " _
& strinterval & "."
%>
1. 错误出现在什么地方
需要注意的是脚本解释器仅指出所发现错误的地方,但实际上那儿并不一定是错误真正出现的地方。在上例中,前面三行的语法正确的;并产生相应的输出结果,而恰恰是第4行引起问题,因为这一行是以一种非法字符开头的,脚本解释器没有意识到这一行是上一行的一部分。
这样的错误是普遍存在的,因为通常我们主要考虑的是要输出的文本内容,而不是双引号、连字符(在vbscript中为“&”)、续行符等的正确顺序。
对于关键字、内部函数名拼写错误或函数的非法参数列表而引起的语法错误,通常比较容易发现,因为错误信息提示可能就指出了错误的实际位置。例如:下面这段代码是想把明天的日期写入页面。
response.write dateadd(now(),"d", 1)
实际得到的结果如图7-3所示:
图7-3 程序执行结果3
这是因为dateadd函数的语法应该是:
dateadd (interval_string, interval_number, start_date)
所以应该改写为如下的代码:
response.write dateadd("d", 1, now())
脚本解释器检测到了我们为第二个参数提供的是一个字符型数据,而dateadd函数需要的是整型数据类型。
代码结构和脚本结构
语法错误的另一个原因是:当制作网页时使用嵌套的或复杂的脚本结构,如if then … else … end if或者do while … loop。这有时会造成难以找到的语法错误。
例如下面这段程序:
<%
if len(request.form("cmdset")) then
strcountername = request.form("lstset")
strnewvalue = request.form("txtset")