【问题标题】:try catch doesn't get date-fns parseISO errortry catch 没有得到 date-fns parseISO 错误
【发布时间】:2021-05-04 11:01:51
【问题描述】:

我似乎犯了一个简单的错误,我编写了这段代码来获取格式化的日期,但如果日期没有正确的字符串来转换,类应该捕获错误但它不起作用并且控制台中显示错误!

import {format,parseISO} from 'date-fns';

class DateFormats {
  // class methods
  constructor(date) { 
    try{
      this.parsedDate = parseISO(date);      
    }
    catch(e){
      this.parsedDate = new Date();
      console.log('catch Error')
    }
   }
 
   get MMM_d_YYYY() {
     return format(this.parsedDate, "MMM d,yyyy")
    }
 
}
 

const wrongDate='2020-*12-20T04:18:21.471275';

console.log(new DateFormats(wrongDate).MMM_d_YYYY);

控制台错误:

RangeError: Invalid time value

有什么想法吗?

【问题讨论】:

  • @HamidShoja Dude,错误来自您的 format 函数,因为它作为字符串出现错误。

标签: javascript reactjs date date-fns


【解决方案1】:

try..catch 只能作为最后的手段使用,因此只能在没有其他选择的情况下使用。

如果一个函数需要特定类型的参数,那么在调用它之前进行检查,不要只使用 try..catch 并在之后处理错误。在这种情况下,date-fns parseISO 函数需要一个字符串来避免 typeError,因此请确保使用字符串调用它,或者可能返回 undefined 或类似值。然后调用者可以检查响应并进行处理。

在这种情况下,如果 catch 块被执行,那么:

this.parsedDate = 'error';

被执行,因此当 MMM_d_YYYY 被访问/调用时,它在期待 Date 对象时调用字符串上的 format,因此 date-fns 会引发错误。

通过调用函数之前检查避免这两个错误,而不是在之后捕获错误。

如果你开始使用 try..catch 来处理不适当的输入,你会强制调用者也使用 try..catch,所以它开始在你的代码中传播.通过处理不正确的输入(例如通过简单地返回一个无效日期),调用者可以使用 if 块检查返回值并以这种方式处理“错误”,这比 try..catch.

在不传递参数的情况下提供默认值也很好,在这种情况下,当前日期和时间似乎合适,所以:

let format = require('date-fns/format')
let parseISO = require('date-fns/parseISO')

class DateFormats {

  // class methods
  // Default is current date and time
  constructor(arg = new Date().toISOString()) {

    // Ensure arg is a string and let date-fns deal with parsing it
    // This might result in an invalid Date, but let the caller
    // deal with that
    this.parsedDate = parseISO(String(arg));
   }
 
   // Return timestamp in MMM d YYYY format or "Invalid Date"
   get MMM_d_YYYY() {

     // this.parsedDate might be an invalid Date, so check first
     // as calling format on an invalid date throws an error
     if (isNaN(this.parsedDate)) {
       return this.parsedDate.toString(); // Invalid Date
     }

     // Otherwise, it's a valid Date so use it
     return format(this.parsedDate, "MMM d,yyyy")
    } 
}
 
// Examples
[void 0,                       // default, no arg   -> Jan 31,2021
 '2020-12-20T04:18:21.471275', // valid timestamp   -> Dec 20,2020
 'fooBar'                      // invalid timestamp -> Invalid Date
].forEach(arg => console.log(arg + ' -> ' + (arg? new DateFormats(arg).MMM_d_YYYY : new DateFormats().MMM_d_YYYY)));

以上可以在npm.runkit运行

【讨论】:

    【解决方案2】:

    当您传递错误的日期时,它会抓住。在正确的位置但在缓存中,您在变量 this.parsedDate 中传递字符串“error”,当您调用 gettter MMM_d_YYYY 时,getter 试图编译的是

    //Value of this.parsedDate which is 'error' because of catch
    return format('error', "MMM d,yyyy")
    

    这个函数抛出一个错误。因为 'error' 字符串不能被格式化。

    import {format,parseISO} from 'date-fns';
    
    class DateFormats {
      // class methods
      constructor(date) { 
        try{
    
          this.parsedDate= parseISO(date);
        }
        catch(e){
          this.parsedDate=parseISO(new Date());
          console.log(this.parsedDate)
        }
       }
     
       get MMM_d_YYYY() {
         return format(this.parsedDate, "MMM d,yyyy")
        }
     
    }
     
    
    const wrongDate='2020-12-20T04:18:21.471275';
    
    console.log(new DateFormats(wrongDate).MMM_d_YYYY);
    

    【讨论】:

    • 如果执行,this.parsedDate = parseISO(new Date()) 将抛出错误,因为 parseISO 要求参数是字符串,而不是对象。你可能会做this.parsedDate = parseISO(new Date().toISOString()),但this.parsedDate = new Date() 做的事情完全相同,而且工作量要少得多。 :-)
    • 正确,但我只是指出您的错误在哪里以及您从控制台中收到该消息的位置。虽然编辑了我的答案结帐。
    • 我不是 OP,所以不是我的错…… ;-)
    猜你喜欢
    • 1970-01-01
    • 2016-01-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-07-25
    相关资源
    最近更新 更多