2013-06-06 27 views
0

我正在寫一個API,它將我們的數據庫的一部分暴露給客戶端。部分API需要在特定條件下發送特定的HTML響應代碼。通過簡單的檢查,這通常很容易,但是我無法看到如何捕獲(例如)將無效日期提交給SQL的'InvalidDateTimeException'錯誤。Coldfusion 8響應特定的錯誤

我已經嘗試轉儲ERROR和cfcatch變量,但是當它們生成巨大的堆棧跟蹤時,我看不到任何可以輕鬆解析的字段來檢查特定類型的錯誤(對文本搜索錯誤消息或堆棧跟蹤)。

我還可以做一個預檢查與正則表達式如

(\ d {4}) - (\ d {2}) - (\ d {2})(\ d {2}) :(\ d {2}):(\ d {2})

但這仍然可能會生成無效日期。 Coldfusion也提供了一些日期驗證,但我已經讀了它是particularly bad。這也不會幫助其他不處理日期的場景。

簡而言之:對ColdFusion中的'InvalidDateTimeException'等特定錯誤做出反應的最佳方式是什麼?

[編輯] 評論的一些澄清 - 我們使用MYSQL 5和cfqueryparams。我們在澳大利亞使用'歐元'日期格式,但如果api用戶提供ISO格式日期(yyyy-mm-dd)以避免混淆,它將會更受歡迎。

+1

一盎司的預防值得一磅的治療。儘管ColdFusion的日期驗證並不完美,但它比InvalidDateTimeExceptions更好。 –

+0

如果您想控制用戶向您發送的內容,cfinput具有掩碼屬性。請注意,如果您預先填充表單域,那麼mask屬性使編輯該值有點棘手。 –

回答

2

嗯....我使用的建議是在錯誤發生之前趕上SQL。您沒有指定您的DBMS(SQL Server,MySQL等),所以我將專注於ColdFusion解決方案。我希望這些建議中的一條能夠指引您走上正確的道路。

選項:

  • 你鏈接到有關ColdFusion的日期驗證的文章中提到的isValid功能推薦的解決方案。按照建議,考慮使用USDATE驗證類型。
  • 如果您使用的是CFC或至少是您的API方法的函數,那麼您可以隨時使用cfargument type =「date」來協助確保日期有效(儘管我的感覺是,它會具有與isDate)
  • 在您的cfquery標記中,您應該使用cfqueryparam來傳遞所有傳遞的參數,尤其是那些直接從用戶傳遞的參數(無論是表單發佈還是API調用)。您應該使用cfqueryparam cfsqltype = CF_SQL_DATE

使用任何上述方法(或全部),你應該換你的ColdFusion代碼在try/catch結構,並有一個更容易的錯誤處理。

根據您的DBMS,您可能也有權訪問Try/catch結構。

****更新:

閱讀有關國際轉換問題您的評論後,我有,我會選擇以下兩種方法:

請記住,我沒有測試過任何代碼或任何東西....

首先,也許國際功能可以幫助你。

http://livedocs.adobe.com/coldfusion/8/htmldocs/help.html?content=functions_in-k_37.html

使用的setlocale的位置設置爲英語(澳大利亞),然後使用LSParseDateTime在YYYY-MM-DD格式的讀取,然後使用日期格式使用MM/DD/YYYY將其寫入到MySQL或無論它期望什麼dateformat。雖然我沒有太多處理這些LS功能的經驗。

第二個選項,使用您提供的正則表達式確保輸入具有正確的結構,然後使用createDate使用解析的mm dd和yyyy元素以美國格式創建日期。使用isValid驗證usdate。

下面是對第二個選項的盲目編碼嘗試。記住,我沒有測試過這個代碼。我大量使用列表函數listGetAt將輸入的日期時間拆分爲單獨的日期和時間字符串,然後使用listGetAt解析出各個日期部分。

<cfscript> 
    isosampledate = "2013-06-05 14:07:33"; 
    passesValidation = false; 
    expectedDatePattern = "\d{4})-(\d{2})-(\d{2}) (\d{2}):(\d{2}):(\d{2}"; 
    try { 
     if (refind(expectedDatePattern,isosampledate)) { 
      datePortion = listGetAt(isosampledate,1," "); 
      timePortion = listGetAt(isosampledate,2," "); 

      yearPart = listGetAt(datePortion,1,"-"); 
      monthPart = listGetAt(datePortion,2,"-"); 
      dayPart = listGetAt(datePortion,3,"-"); 

      hoursPart = listGetAt(timePortion,1,":"); 
      minutesPart = listGetAt(timePortion,2,":"); 
      secondsPart = listGetAt(timePortion,3,":"); 

      thisUSDate = createDateTime(yearPart,monthPart,dayPart,hoursPart,minutesPart,secondsPart) 

      if (isValid("usdate",thisUSDate) { 
       passesValidation = true; 
       sqlDate = CreateODBCDateTime(thisUSDate); 
      } 
     } 
    } catch (e:any) { 
     passesValidation = false; 
    } 
</cfscript> 

我敢肯定,這些日期函數,如果輸入的值不是一個有效的日期則至少有一個會拋出這將由catch塊得到拿起一個例外。

希望這會有所幫助。我去睡了。

+0

謝謝。我沒有忘記提及我們使用的是MYSQL 5數據庫,而且我一直在使用cfqueryparams--它們是產生錯誤的原因。 我們也有使用澳大利亞(這是歐元的coldfusion)格式的問題,但我期待用戶發送ISO格式的數據(yyyy-mm-dd)。我不認爲這是由isValid支持(請糾正我,如果我錯了)。 - 輸入代替換檔輸入 –

+0

剛更新我的解決方案...希望它有幫助。 –

+0

是的,幫助。在我的實現中,我可能會執行此檢查,然後使用SQLDate對象將日期加載到數據庫中。 我沒有想到將ODBCDateTime對象保存在變量中,所以最有助於。這將從通用數據庫錯誤中分離出InvalidDate錯誤,這正是我想要解決的問題。 –