0

我正在编写一个 API,它将我们的部分数据库公开给客户端。此 API 的一部分需要针对特定​​条件发送某些 HTML 响应代码。这通常通过简单的检查很容易,但我看不到如何捕获(例如)无效日期提交给 SQL 的“InvalidDateTimeException”错误。

我已经尝试转储 ERROR 和 cfcatch 变量,但是虽然它们会生成巨大的堆栈跟踪,但我看不到任何易于解析以检查特定类型的错误的字段(缺少对错误消息或堆栈跟踪进行文本搜索)。

我还可以使用正则表达式进行预检查,例如

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

但这仍然会产生无效的日期。Coldfusion 还提供了一些日期验证,但我读到它特别糟糕。这也无助于不处理日期的其他场景。

简而言之:对冷融合中的“InvalidDateTimeException”等特定错误做出反应的最佳方法是什么?

[编辑] 评论中的一些澄清 - 我们使用的是 MYSQL 5 和 cfqueryparams。我们在澳大利亚使用“欧元”日期格式,但如果 api 用户提供 ISO 格式日期 (yyyy-mm-dd) 以避免混淆,则更可取。

4

1 回答 1

2

嗯....我的建议是在错误到达 SQL 之前捕获它。您没有指定您的 DBMS(SQL Server、MySQL 等),所以我将专注于 ColdFusion 解决方案。我希望这些建议之一能为您指明正确的道路。

选项:

  • 您链接到的有关 Coldfusion 日期验证的文章提到了 isValid 函数作为推荐的解决方案。按照建议,考虑将其与 USDATE 验证类型一起使用。
  • 如果您在 API 方法中使用 CFC 或至少 cffunctions,那么您可以使用 cfargument type="date" 来帮助确保日期有效(尽管我的感觉是与 isDate 具有相同的宽松行为)
  • 在您的 cfquery 标记内,您应该将 cfqueryparam 用于您传递的所有参数,尤其是那些直接从用户传递的参数(无论是表单发布还是 API 调用)。您应该使用 cfqueryparam cfsqltype=CF_SQL_DATE

使用上述任何一种方法(或所有方法),您应该将您的冷融合代码包装在一个 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 格式读取,然后使用 dateformat 使用 mm/dd/yyyy 或它期望的任何日期格式将其写入 mySQL。不过,我在处理这些 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 块拾取。

希望这可以帮助。我要去睡觉了。

于 2013-06-06T02:20:43.683 回答