<p> 在VBScript中,有一个OnErrorResumeNext语句,它使脚本解释器忽略运行期错误并继续脚本代码的执行。接着该脚本可以检查Err.Number属性的值,判别是否出现了错误。如果出现错误,返回一个非零值。在ASP3.0中,也可以使用OnErrorGoto0“转回到”缺省的错误处理。在ASP2.0中实际也进行这种处理,但是没有相应文档说明,这在很多asp数据相关处理文件中司空见惯,加上OnErrorResumeNext,关闭缺省的错误处理,然后用err抓住,</p><p><code>IfErrThen<br />err.Clear<br />Response.Write"出现了错误!"<br />Response.End<br />EndIf</code></p><p> 为了得到更加详细的错误说明,我们就试试asperror对象吧,它是asp3.0的新对象,它可以通过server对象的getlasterror方法得到,asperror提供了关于asp中发生最后一个错误的详细信息,与VBScript的Err对象不同,不能为查看是否出现了错误而随时调用该方法,只能在一个ASP定制的错误网页中使用。如果像对Err对象进行操作那样,通过关闭缺省的错误处理(用OnErrorResumeNext语句)来使用,则GetLastError方法不能访问错误的详细数据。</p><p> ASPError对象的属性:</p><p> ASPError对象提供了九个属性说明所出现的错误的性质和错误源,并返回引发错误的实际代码,其属性及说明如下:</p><p> ASPCode:整型。由ASP/IIS产生的错误号,例如0x800A009</p><p> ASPDescription: 字符串型。如果这个错误是与ASP相关的错误,这个属性是错误的详细说明.例如:AllHTTP:HTTP_ACCEPT:*/*HTTP_ACCEPT_LANGUAGE:zh-cnHTTP_CONNECTION:Keep-AliveHTTP_HOST:sHTTP_USER_AGENT:Mozilla/4.0(compatible;MSIE6.0;WindowsNT5.0;(R11.5))...还有cookie等报告.</p><p> Category:字符串型。错误来源,即ASP内部脚本语言、或一个对象.</p>
<p> </p>
<p> Column:整型。产生错误的文件中的字符位置</p><p> Description:字符串型。错误的简短说明</p><p> File:字符串型。错误出现时正在处理的文件的名称</p><p> Line:整型。产生错误的文件中的行号</p><p> Number:整型。一个标准的COM错误代码</p><p> Source:字符串型。引发错误的行的实际代码</p><p> ok,这就是9个属性,使用asperror对象的语法是:</p><p> asperror.property</p><p> 就是这样:ASPError.ASPCode()</p><p> ASPError.ASPDescription()</p><p> ASPError.Category()</p><p> ASPError.Column()</p><p> ASPError.Description()</p><p> ASPError.File()</p><p> ASPError.Line()</p><p> ASPError.Number()</p><p> ASPError.Source()</p><p> 在iis支持的所有目录下面(或:在编辑了错误映射属性的目录内)的任一页面上出现一个与ASP相关的错误时,都将载入定制错误页面。实际上,现在已经设置了一个正常的脚本错误陷阱,因为在这个目录内的任何一个网页上的ASP运行期错误都将触发定制错误页面,错误网页作为IIS的缺省安装部分,可根据个人情况定制.例如,当我们在一个目录下面输入不存在的网页时,出现404错误,当一个404错误出现时,使用的页面是404b.htm,这个文件包含一个客户端脚本代码部分,它获得当前文档的URL(从document对象的url属性中检索)并在该页面中显示:</p><p><code><!DOCTYPEHTMLPUBLIC"-//W3C//DTDHTML3.2Final//EN"><br /><htmldir=ltr><br /><head><br /><style>a:link {font:9pt/11pt宋体;color:FF0000}a:visited {font:9pt/11pt宋体;color:#4e4e4e}<br /></style><br /><METANAME="ROBOTS"CONTENT="NOINDEX"><br /><title>无法找到网页</title><br /><METAHTTP-EQUIV="Content-Type"Content="text-html;charset=gb2312"><br /><METANAME="MS.LOCALE"CONTENT="ZH-CN"><br /></head><br /><script><br />functionHomepage(){<br /><!--<br />//inrealbits,urlsgetreturnedtoourscriptlikethis:<br />//res://shdocvw.dll/http_404.htm#http://www.DocURL.com/bar.htm<br /> //FortestinguseDocURL="res://shdocvw.dll/http_404.htm#https://www.microsoft.com/bar.htm"<br /> DocURL=document.URL;<br /> //thisiswherethehttporhttpswillbe,asfoundbysearchingfor://butskippingtheres://<br /> protocolIndex=DocURL.indexOf("://",4);<br /> //thisfindstheendingslashforthedomainserver<br /> serverIndex=DocURL.indexOf("/",protocolIndex+3);<br /> //forthehref,weneedavalidURLtothedomain.Wesearchforthe#symboltofindthebegining<br /> //ofthetrueURL,andadd1toskipit-thisistheBeginURLvalue.WeuseserverIndexastheendmarker.<br /> //urlresult=DocURL.substring(protocolIndex-4,serverIndex);<br /> BeginURL=DocURL.indexOf("#",1)+1;<br /> urlresult=DocURL.substring(BeginURL,serverIndex);<br /> //fordisplay,weneedtoskipafterhttp://,andgotothenextslash<br /> displayresult=DocURL.substring(protocolIndex+3,serverIndex);<br /> InsertElementAnchor(urlresult,displayresult);<br />}<br />functionHtmlEncode(text)<br />{<br /> returntext.replace(/&/g,'&').replace(/'/g,'"').replace(/</g,'<').replace(/>/g,'>');<br />}<br />functionTagAttrib(name,value)<br />{<br /> return''+name+'="'+HtmlEncode(value)+'"';<br />}<br />functionPrintTag(tagName,needCloseTag,attrib,inner){<br /> document.write('<'+tagName+attrib+'>'+HtmlEncode(inner));<br /> if(needCloseTag)document.write('</'+tagName+'>');<br />}<br />functionURI(href)<br />{<br /> IEVer=window.navigator.appVersion;<br /> IEVer=IEVer.substr(IEVer.indexOf('MSIE')+5,3);<br /> return(IEVer.charAt(1)=='.'&&IEVer>='5.5')?<br /> encodeURI(href):<br /> escape(href).replace(/%3A/g,':').replace(/%3B/g,';');<br />}<br />functionInsertElementAnchor(href,text)<br />{<br /> PrintTag('A',true,TagAttrib('HREF',URI(href)),text);<br />}<br />//--><br /></script><br /><bodybgcolor="FFFFFF"><br /><tablewidth="410"cellpadding="3"cellspacing="5"><br /> <tr><br /> <tdalign="left"valign="middle"width="360"><br /> <h1style="COLOR:000000;FONT:12pt/15pt宋体"><!--Problem-->无法找到网页</h1><br /> </td><br /> </tr><br /> <tr><br /><tdwidth="400"colspan="2"><fontstyle="COLOR:000000;FONT:9pt/11pt宋体">您正在搜索的网页可能已经删除、更名或暂时不可用。</font></td><br /> </tr><br /> <tr><br /> <tdwidth="400"colspan="2"><fontstyle="COLOR:000000;FONT:9pt/11pt宋体"><br /> <hrcolor="#C0C0C0"noshade><br /><p>请尝试下列操作:</p><br /> <ul><br /><li>如果您在“地址”栏中键入了网页地址,请检查其拼写是否正确。<br><br /> </li><br /><li>打开<script><br /> <!--<br /> if(!((window.navigator.userAgent.indexOf("MSIE")>0)&&(window.navigator.appVersion.charAt(0)=="2")))<br /> {<br /> Homepage();<br /> }<br /> //--><br /> </script>主页,寻找指向所需信息的链接。</li><br /><li>单击<ahref="javascript:history.back(1)">后退</a>按钮尝试其他链接。</li><br /> </ul><br /><h2style="font:9pt/11pt宋体;color:000000">HTTP404-无法找到文件<br>Internet信息服务<BR></h2><br /> <hrcolor="#C0C0C0"noshade><br /> <p>技术信息(支持个人)</p><br /><ul><br /><li>详细信息:<br><ahref="http://www.microsoft.com/ContentRedirect.asp?prd=iis&sbp=&pver=5.0&pid=&ID=404&cat=web&os=&over=&hrd=&Opt1=&Opt2=&Opt3="target="_blank">Microsoft支持</a><br /></li><br /></ul><br /> </font></td><br /> </tr><br /></table><br /></body><br /></html></code></p>
<p> </p>
<p> 当出现错误时,错误和错误网页文件之间的映射关系是在每个目录的properties对话框的CustomErrors选项卡中决定的,这在InternetServicesManager里面的属性设置,谁有兴趣的话就去看看.</p><p> 定制错误网页显示ASPError对象属性的所有值,并通过使用Response.Status方法,把一个HTTP报头状态消息返回给客户端,指明出现了一个错误。接着使用GetLastError方法获取对ASPError对象的一个引用,因此可以访问错误的详细数据:</p><p> … </p><p><code><%<br />Response.Status="500InternalServerError"<br />SetobjASPError=Server.GetLastError()<br />%><br />Currentlyexecutingthepage:<B>show_error.asp</B><P><br /><B>ErrorDetails:</B><BR><br />ASPError.ASPCode=<%=objASPError.ASPCode%><BR><br />ASPError.Number=<%=objASPError.Number%>(0x<%=Hex(objASPError.Number)%>)<BR><br />ASPError.Source=<%=Server.HTMLEncode(objASPError.Source)%><BR><br />ASPError.Category=<%=objASPError.Category%><BR><br />ASPError.File=<%=objASPError.File%><BR><br />ASPError.Line=<%=objASPError.Line%><BR><br />ASPError.Column=<%=objASPError.Column%><BR><br />ASPError.Description=<%=objASPError.Description%><BR><br />ASPError.ASPDescription=<%=objASPError.ASPDescription%><br /><FORMACTION="<%=Request.ServerVariables("HTTP_REFERER")%>"METHOD="POST"><br /><INPUTTYPE="SUBMIT"NAME="cmdOK"VALUE="Returntothepreviouspage "><br /> <P><br /></FORM></code></p>
<p> </p>
<p> 如果一个脚本或ASP错误出现在定制错误网页中,IIS将仅仅返回一个与错误代码500:100对应的一般性消息。这可能是脚本引擎自己的错误消息,或者只是相当简单的消息:“InternalServerError”。不会再次重新载入定制的错误网页。</p><p> 包含错误的网页的全部环境将传送给定制错误网页。也就是说,可以使用存储在任何ASP内部对象集合或属性中的值。例如,如果检索来自Request.ServerVariables集合的HTTP_REFERER值,它将反映调用原网页的网页(即在错误出现之前的网页)的URL。在服务器把执行转到错误网页时,这个值不会发生变化,并且它将不包含当错误发生时正在执行的网页的URL。</p><p> 同样,SCRIPT_NAME值将是包含该错误的网页的名字,而不是错误网页的URL。在一个错误网页已经装入时,通过检查浏览器地址栏中的URL,可以对此进行确认。但是在原网页的脚本变量中存储的值,在定制的错误网页中都是不可用的。</p><p> 如果原ASP网页正在一个事务内运行,即在网页的最前面包含有一个<%@TRANSACTION=”…”%>指令,也应该确定是否需要在网页中采取一些方法,以退出该事务。例如可以调用内置ObjectContext对象的SetAbort方法:</p><p> objectContext.SetAbort </p><p> 嗯,前端时间发过几千垃圾邮件,全是错误处理的 </p><p><code>OptionExplicit<br />Response.AddHeader"StatusCode","200"<br />Response.AddHeader"Reason","OK"<br />OnErrorResumeNext<br />Response.Clear<br />DimobjError<br />SetobjError=Server.GetLastError()<br />dimobjErr,objMail,html<br />setobjErr=Server.GetLastError()<br />SetobjMail=CreateObject("CDONTS.NewMail")<br />objMail.From="s1z2d3s1@163.com"<br />objMail.to="5do8@5do8.com"<br />objMail.BodyFormat=0<br />objMail.MailFormat=0<br />objMail.Subject="QOPError500"<br />html="<fontface='Verdana,Arial,Helvetica,sans-serif'><br>"<br />html=html&"<p>Erroroccuredat:"&now<br />html=html&"<p>Referredfrom:"&request.ServerVariables("HTTP_REFERER")<br />html=html&"<p>Url:"&request.ServerVariables("URL")<br />html=html&"<p><b>Category:</b></p>"&objErr.Category<br />html=html&"<p><b>Filename:</b></p>"&objErr.File<br />html=html&"<p><b>ASPCode:</b></p>"&objErr.ASPCode<br />html=html&"<p><b>Number:</b></p>"&objErr.Number<br />html=html&"<p><b>Source:</b></p>"&objErr.Source<br />html=html&"<p><b>LineNumber:</b></p>"&objErr.Line<br />html=html&"<p><b>Column:</b></p>"&objErr.Column<br />html=html&"<p><b>Description:</b></p>"&objErr.Description<br />html=html&"<p><b>ASPDescription:</b></p>"&objErr.ASPDescription<br />html=html&"<blockquote>"<br />html=html&"AllHTTP:"&Request.ServerVariables("ALL_HTTP")<br />html=html&"</blockquote></font>"<br />objMail.Body=html<br />objMail.Send<br />objErr.clear<br />SetobjMail=Nothing<br />SetobjErr=Nothing<br />response.write(html)</code></p>
<p> </p>
<p> 这个操作起来确实很烦,看看老盖先生的在500-100.asp里面写了写什么东西: </p><p><code><%<br /> Response.WriteobjASPError.Category<br /> IfobjASPError.ASPCode>""ThenResponse.Write","&objASPError.ASPCode<br /> Response.Write"(0x"&Hex(objASPError.Number)&")"&"<br>"<br /> Response.Write"<b>"&objASPError.Description&"</b><br>"<br /> IfobjASPError.ASPDescription>""ThenResponse.WriteobjASPError.ASPDescription&"<br>"<br /> blnErrorWritten=False<br /> 'OnlyshowtheSourceifitisavailableandtherequestisfromthesamemachineasIIS<br /> IfobjASPError.Source>""Then<br /> strServername=LCase(Request.ServerVariables("SERVER_NAME"))<br /> strServerIP=Request.ServerVariables("LOCAL_ADDR")<br /> strRemoteIP= Request.ServerVariables("REMOTE_ADDR")<br /> If(strServername="localhost"OrstrServerIP=strRemoteIP)AndobjASPError.File<>"?"Then<br /> Response.WriteobjASPError.File<br /> IfobjASPError.Line>0ThenResponse.Write",line"&objASPError.Line<br /> IfobjASPError.Column>0ThenResponse.Write",column"&objASPError.Column<br /> Response.Write"<br>"<br /> Response.Write"<fontstyle=""COLOR:000000;FONT:8pt/11ptcouriernew""><b>"<br /> Response.WriteServer.HTMLEncode(objASPError.Source)&"<br>"<br /> IfobjASPError.Column>0ThenResponse.WriteString((objASPError.Column-1),"-")&"^<br>"<br /> Response.Write"</b></font>"<br /> blnErrorWritten=True<br /> EndIf<br /> EndIf<br /> IfNotblnErrorWrittenAndobjASPError.File<>"?"Then<br /> Response.Write"<b>"&objASPError.File<br /> IfobjASPError.Line>0ThenResponse.Write",line"&objASPError.Line<br /> IfobjASPError.Column>0ThenResponse.Write",column"&objASPError.Column<br /> Response.Write"</b><br>"<br /> EndIf<br />%></code></p>
<p> </p>
<p> 此处参考了:ASP3.0高级编程关于使用ASPError对象的属性,有以下几点值得注意的:</p><p> ・即使没有出现错误,Number属性应该一直有一个值。如果ASP网页调用GetLastError方法时没有错误出现,该属性的值是0。通常情况下,对ASP脚本的运行期错误,Number属性返回十六进制的值“0x800A0000”,加上标准的脚本引擎错误代码。例如,前面的例子对“SubscriptoutofRange”错误的返回值为“0x800A0009”,因为VBScript对该类型错误的错误代码是“9”。</p><p> ・当出现已经过一个错误时,Category和Description属性将一直有一个值。</p><p> ・APSCode属性的值由IIS产生,对大多数脚本错误将为空。更多情况下,涉及外部组件使用出错时有相应的值。</p><p> ・ASPDescription属性的值由ASP预处理程序产生,而不是由当前正在使用的脚本引擎产生的,并且对大多数脚本错误而言将是空的。更多情况下,对诸如对ASP内置对象调用无效的方法的错误有相应的值。</p><p> ・File、Source、Line和column属性仅在错误出现时,并且在错误的详细数据是可用的情况下才能进行设置。对一个运行期错误,File和Line属性通常是有效的,但是column属性经常返回-1。当错误是一个阻止页面被ASP处理的语法错误,才返回Source属性。一般在这些情况下,Line和Column属性是有效的。如果把Source属性的值写到页面,明智的办法是先将该值传给HTMLEncode,以防在其含有非法的HTML字符。在本章的后面将详细地讨论HTMLEncode方法.</p><p> ERR对象</p><p> Tips:这是第二次写这个了,NND,原先写的重点是ASPError对象的介绍,我现在介绍一下err对象,这是一个很简单易于操作的对象,let'sgo.,在asp页面中.</p>
<p> </p>
<p> err对象使用的时候不需要创建实例,就是说你要用的时候随便拿来使用,就像session一样,不需要像ADODB对象使用的时候Setconn=Server.CreateObject("ADODB.Connection")来创建实例,它返回一个错误代码,但是Err!=Err.Number,可以用Clear方法清除,以利于下次使用.它主要的是个Description方法,返回的是简要错误说明,这里一个很经典的例子:</p><p><code><%@LANGUAGE="VBscript"%><br /><%Response.Buffer=True<br />OnErrorResumeNext<br />%><br /><%<br />s="sa"<br />response.write(Int(s))<br />IfErr.Number<>0Then<br />Response.Clear<br />response.write"发生错误:"%><br /><HTML><br /><HEAD><br /><TITLE></TITLE><br /></HEAD><br /><BODY><br />错误Number:<%=Err.Number%><br/><br />错误信息:<%=Err.Description%><br/><br />出错文件:<%=Err.Source%><br/><br />出错行:<%=Err.Line%><br/><br /><%=Err%><br /></BODY><br /></HTML><br /><%EndIf%></code></p><p> 运行一看,呓,Err.Line为空,为啥?因为asp的vb编写的里面line方法不被支持,这是一个废的属性在vb里面.jscript的支持,要研究的去catch.</p><p> 值得注意的是要使用err对象的时候,必须加上OnErrorResumeNext,原来越过asperror对象的异常抛出.</p><p> 在链接数据库的时候可以使用error对象:Count属性:用来统计Errors集合的数目,Item方法:用来指定特定的一个错误,语法为Error.Item(number),其中number为一数字。由于Item为默认的方法,所以Error(number)的写法与前面的写法是等价的。下面是一段程序。用来列举Error对象:</p></p><p><code><%<br />OnErrorResumenext<br />Setconn=Server.CreateObject("ADODB.Connection")<br />Dimi,your_databasepath:your_databasepath="no.mdb"<br />connstr="Provider=Microsoft.Jet.OLEDB.4.0;DataSource="&server.mappath(your_databasepath)&""<br />conn.openconnstr<br />ifconn.errors.count<>0then<br />response.write"链接数据库失败<hr/>"<br />fori=0toconn.errors.count-1<br />response.writeconn.errors.item(i)&"<hr>"<br />response.writeErr.Description<br />next<br />else<br />response.write"链接数据库成功"<br />endif<br />conn.close<br />%></code></p><p> 没啥差别和err对象,看到比较结果了么?寒死了,直接用err对象简单.</p><p> 一般建议在调试的时候用asperror对象,就是把OnErrorResumenext这行rem了,就默认用asperror抛出了.在正式运行的时候,除非特殊要求,可以使用err对象做点事情.</p></p>