【问题标题】:Ignore JSON parsing error if a field returns TypeError如果字段返回 TypeError,则忽略 JSON 解析错误
【发布时间】:2020-04-16 22:28:42
【问题描述】:

这感觉像是一个完全直接的 try/catch 问题,但作为一个 javascript 新手,我显然遗漏了一些东西。

我正在尝试解析来自克利夫兰艺术博物馆开放收藏 API 的数据。一切都很好,除了一些作品没有说出所涉及的艺术家的名字。

当元数据中包含艺术家时(例如 here),此 sn-p 有效地提取它:

jsonObj['data'][0]['creators'][0]['description']

当元数据中没有艺术家时(例如here),我得到一个

TypeError: jsonObj.data[0].creators[0] 未定义

错误。

互联网表明这是使用 try/catch 语句的最佳时机:

var data_author = tryCatch(jsonObj['data'][0]['creators'][0]['description'])

var function_image_data = [data_author]

function tryCatch(json_address) {
    try {
         output_json_data = json_address
     }
     catch (e) {
         output_json_data = ''

     }

      return output_json_data
  }

虽然这在有作者条目时有效,但在出现错误时似乎没有影响。我从这个陈述中遗漏了什么非常明显的东西?

谢谢!

编辑:根据以下 tex 的建议,我将尝试从函数中获取数据并直接放入代码中。我不完全确定它为什么会起作用,但它确实避免了在事情到达函数之前就被评估的可能性。搜索作品所有元素的部分现在如下所示:

    var data_tombstone = tryCatch(jsonObj['data'][0]['tombstone'])
    console.log(data_tombstone)
    var data_title = tryCatch(jsonObj['data'][0]['title'])
    try {
         data_author = jsonObj['data'][0]['creators'][0]['description']
     }
     catch (e) {
         data_author = ''

     }
    var data_creation_date = tryCatch(jsonObj['data'][0]['creation_date'])

【问题讨论】:

  • 您可以发布示例 json 以及您正在解析的代码部分吗?谢谢。
  • 对不起!链接没有发布。我刚刚更新了这个问题,链接到一个有创作者的条目和一个没有的条目。谢谢!
  • 这对我来说看起来像是伪代码。我认为如果您发布一些您正在尝试开始工作的实际代码,您会有更好的运气。
  • 这是我正在使用的实际代码的 sn-p。我刚刚编辑了问题以包括函数的调用和我将结果添加到的数组。如果您需要其他任何内容,我很乐意添加。

标签: javascript json api error-handling


【解决方案1】:

jsonObj['data'][0]['creators'][0]['description'] 在你的 tryCatch 函数被调用之前被评估,这意味着错误不会被捕获。

如果你愿意使用图书馆,我建议Ramda。这是一个使用 Ramda 的解决方案(不涉及try..catch

const works = { data: [{ creators: [{ description: 'an author'}] }] }
const doesntWork = { data: [{ creators: [] }] }

const getAuthor = R.pathOr('', ['data', 0, 'creators', 0, 'description'])

const data_author_works = getAuthor(works)

const data_author_doesnt_work = getAuthor(doesntWork)

console.log('works: ', data_author_works)
console.log('doesn\'t work: ', data_author_doesnt_work)
<script src="https://cdnjs.cloudflare.com/ajax/libs/ramda/0.26.1/ramda.min.js"></script>

如果您不想使用库,但确实想使用 try...catch,则需要执行以下操作,但我不推荐这种方法:

const works = { data: [{ creators: [{ description: 'an author'}] }] }
const doesntWork = { data: [{ creators: [] }] }

const getAuthor = jsonData => {
  try {
    return jsonData.data[0].creators[0].description
  }
  catch (e) {
    return ''
  }
}

const data_author_works = getAuthor(works)
const data_author_doesnt_work = getAuthor(doesntWork)

console.log('works: ', data_author_works)
console.log('doesn\'t work: ', data_author_doesnt_work)

【讨论】:

  • 抱歉,我不确定这是什么意思。在 tryCatch 函数之前它在哪里被评估?我认为第一行将 'jsonObj['data'][0]['creators'][0]['description']' 传递给第三行中的函数,然后在 try 语句中对其进行评估。这显然是不正确的,但我不明白哪里出错了。谢谢!
  • jsonObj['data'][0]['creators'][0]['description'] 是一个表达式。 JS 引擎将尝试评估该表达式并调用 tryCatch 与表达式评估的任何内容。如果没有艺术家信息,您将在调用 tryCatch 之前收到错误消息。要确认这一点,您可以在函数内的 try 之前的行上添加 console.log 语句。如果缺少艺术家信息,您会看到没有任何记录。
  • 太棒了,谢谢!我最终只是将该部分从函数中拉出并直接在线运行。感谢您帮助我解决问题!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-09-30
  • 2011-03-27
  • 1970-01-01
  • 1970-01-01
  • 2022-01-04
  • 2019-06-26
相关资源
最近更新 更多