为什么我不能在Coldfusion cftry / cfcatch语句中捕获错误消息?

时间:2012-10-02 21:42:11

标签: coldfusion error-handling try-catch

我有一个表格,我可以上传很多徽标。我在cftry/cfcatch语句中验证文件(空表单字段,错误扩展名,...)。

当我在cftry中发现错误时,我会这样做:

 <cfthrow type="FileNotFound" message="#tx_settings_app_error_create_first#" />

并在我的'cfcatch'中

 <cfcatch>
    <cfoutput><script type="text/javascript">window.onload = function(){alert("#cfcatch.message#");window.location.href="hs_apps.cfm"; } </script></cfoutput>
 </cfcatch>

这样可以正常工作,捕获所有错误并提醒用户有什么问题。

现在我想在数据库调用中使用相同的处理程序,我正在检查重复的用户名。还是一样:

 <cfquery datasource="#Session.datasource#" name="duplicates">
      SELECT a.app_alias 
      FROM apps AS a
      WHERE a.iln = <cfqueryparam value = "#Session.loginID#" cfsqltype="cf_sql_varchar" maxlength="13"> 
      AND a.app_alias = <cfqueryparam value = "#form.app_basic_alias#" cfsqltype="cf_sql_varchar" maxlength="50">
 </cfquery>
 <cfif duplicates.recordcount GT 0>
      <cfthrow type="FileNotFound" message="#tx_settings_apps_error_dup#" />
 </cfif>

cfcatch也是一样的。

然而。现在这会产生一个服务器错误页面,我被抛弃了。

问题
任何想法,为什么我都在努力让cftry/cfcatch在这里工作?我很傻。

谢谢!

修改
这是完整的代码

<cfif isDefined("send_basic")>
    <cfset variables.timestamp = now()>
    <cfset variables.orderview = "1">

    <cfif form.send_basic_type EQ "new">
    <cftry> 
        <cfif module_check.recordcount GT 0>
            <cfloop query="module_check">
                <cfif module_check.module_name EQ "preorder">
                    <cfset variables.module_name = module_check.module_name>
                    <cfset variables.b2b_preord_ok = "true">
                </cfif>
            </cfloop>
            <cfif form.app_basic_orderview EQ "preo">
                <cfset variables.orderview = "0">
            </cfif>
        </cfif>

        <!--- PROBLEM HERE: DUPLICATES --->
        <cfquery datasource="#Session.datasource#" name="duplicates">
            SELECT a.app_alias 
                FROM apps AS a
                WHERE a.iln = <cfqueryparam value = "#Session.loginID#" cfsqltype="cf_sql_varchar" maxlength="13"> 
                AND a.app_alias = <cfqueryparam value = "#form.app_basic_alias#" cfsqltype="cf_sql_varchar" maxlength="50">
        </cfquery>
        <cfif duplicates.recordcount GT 0>
            <cfthrow type="FileNotFound" message="#tx_settings_apps_error_dup#" />
        </cfif>

        <!--- IF PASS, CREATE/UPDATE --->
        <cfquery datasource="#Session.datasource#">
            INSERT INTO apps ( ... )
            VALUES( ...  )
        </cfquery>
        <cfset variables.app_action = "Applikation erstellt">

        <!--- success --->
        <cfoutput><script type="text/javascript">window.onload = function(){alert("#tx_settings_app_cfm_create#");}</script></cfoutput>

        <cfcatch>
            <cfoutput><script type="text/javascript">window.onload = function(){alert("#tx_settings_app_err_create#");}</script></cfoutput>
        </cfcatch>
    </cftry>
<cfelse>
    <cftry>

        <!--- UPDATE --->
        <cfquery datasource="#Session.datasource#">
            UPDATE apps
                SET   ... = ...
        </cfquery>
        <cfset variables.app_action = "Applikation aktualisiert">
        <!--- success --->
        <cfoutput><script type="text/javascript">window.onload = function(){alert("#tx_settings_app_cfm_update#");}</script></cfoutput>
        <cfcatch>
            <cfoutput><script type="text/javascript">window.onload = function(){alert("#tx_settings_app_err_update#");}</script></cfoutput>
        </cfcatch>
    </cftry>        
</cfif>

</cfif>

错误消息我收到了我指定的消息=

 <cfthrow type="FileNotFound" message="#tx_settings_apps_error_dup#" />

如果被捕,应提醒tx_settings_apps_error_dup后面的文字。如果我转储cfcatchcfcatch.message是我指定的文本,那么错误就会被捕获,只有我得到服务器错误页面而不是警报。我正在使用与文件上载和表单提交完全相同的处理程序。我不明白为什么它不在这里工作?

感谢您的帮助!

WORKAROUD
注意不错,但足够了:

<cfif dups.recordcount NEQ 0>
    <cfoutput><script type="text/javascript">window.onload = function(){alert("#tx_settings_apps_error_dup#"); location.href = "hs_apps_detail.cfm?create=newApp&id=none";}</script
    </cfoutput>
    <cfabort> 
</cfif>

因此,当找到重复项时,我会提醒用户,重新加载完全相同的页面并cfabort以防止旧页面进一步处理。补丁即是。

1 个答案:

答案 0 :(得分:3)

(将其从仅仅评论中移除)

好的,所以如果您能够将其转储,那么抓住肯定会抓住异常,所以并​​不是因为尝试/抓住它不起作用,它是其他的东西。请记住,处理将持续到catch块之后的请求结束,然后才会刷新输出缓冲区,并将alert()发送到浏览器。听起来像是在输出警报后,处理继续,发生了一些其他错误,导致服务器的错误页面显示。我建议暂时删除错误页面并注意CF正在提高的实际错误。

注意:如果您想在输出alert()后立即在catch块中停止处理,那么您需要告诉CF,即:使用<cfabort>。否则,如上所述,它会继续前进。

我认为服务器错误页面捕获的异常仍记录在异常日志中,但我可能错了。您总是可以在onError()中放置Application.cfc处理程序,记录发生的任何错误,然后重新抛出错误,以便错误页面仍处理它。这样你就得到了关于错误的信息,并且下注者仍然可以看到错误的错误页面。