如何正确处理 IcedCoffeeScript 的错误? [英] How to correctly handle errors with IcedCoffeeScript?

查看:42
本文介绍了如何正确处理 IcedCoffeeScript 的错误?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

node.js 中的常见做法是将错误消息作为第一个参数返回给回调函数.在纯 JS(Promise、Step、seq 等)中有许多解决方案可以解决这个问题,但它们似乎都不能与 ICS 集成.在不损失可读性的情况下处理错误的正确解决方案是什么?

It is common practice in node.js to return error message as the first argument to a callback function. There are a number of solutions to this problem in pure JS (Promise, Step, seq, etc), but none of them seem to be integrable with ICS. What would be correct solution to handle errors without losing much of readability?

例如:

# makes code hard to read and encourage duplication
await socket.get 'image id', defer err, id
if err # ...
await Image.findById id, defer err, image
if err # ...
await check_permissions user, image, defer err, permitted
if err # ...


# will only handle the last error
await  
  socket.get 'image id', defer err, id
  Image.findById id, defer err, image
  check_permissions user, image, defer err, permitted

if err  # ...


# ugly, makes code more rigid
# no way to prevent execution of commands if the first one failed
await  
  socket.get 'image id', defer err1, id
  Image.findById id, defer err2, image
  check_permissions user, image, defer err3, permitted

if err1 || err2 || err3  # ...

推荐答案

我通过样式和编码约定解决了这个问题.它确实一直出现.让我们把你的片段放在下面,再充实一点,这样我们就有了一个可行的功能.

I solve this problem through style and coding convention. And it does come up all the time. Let's take your snippet below, fleshed out a little bit more so that we have a workable function.

my_fn = (cb) ->
  await socket.get 'image id', defer err, id
  if err then return cb err, null
  await Image.findById id, defer err, image
  if err then return cb err, null
  await check_permissions user, image, defer err, permitted
  if err then return cb err, null
  cb err, image

你说的很对,这很难看,因为你在很多地方都把代码短路了,而且你需要记住每次返回时都要调用 cb.

You're exactly right, this is ugly, because you are short-circuiting out of the code at many places, and you need to remember to call cb every time you return.

您提供的其他片段会产生不正确的结果,因为它们会在需要序列化的地方引入并行性.

The other snippets you gave yield incorrect results, since they will introduce parallelism where serialization is required.

我个人的 ICS 编码约定是:(1)从一个函数中只返回一次(控制权落在最后);(2) 尝试在同一缩进级别处理所有错误.用我喜欢的风格重写你所拥有的:

My personal ICS coding conventions are: (1) return only once from a function (which control falls off the end); and (2) try to handle errors all at the same level of indentation. Rewriting what you have, in my preferred style:

my_fn = (cb) ->
  await socket.get 'image id', defer err, id 
  await Image.findById id, defer err, image                   unless err?
  await check_permissions user, image, defer err, permitted   unless err?
  cb err, image

在socket.get调用出错的情况下,需要检查两次错误,显然两次都会失败.我不认为这是世界末日,因为它使代码更干净.

In the case of an error in the socket.get call, you need to check the error twice, and it will obviously fail both times. I don't think this is the end of the world since it makes the code cleaner.

或者,您可以这样做:

my_fn = (autocb) ->
  await socket.get 'image id', defer err, id
  if err then return [ err, null ]
  await Image.findById id, defer err, image
  if err then return [ err, null ]
  await check_permissions user, image, defer err, permitted
  return [ err, image ]

如果您使用 autocb,这不是我最喜欢的 ICS 功能,那么每当您返回/短路函数时,编译器都会为您调用 autocb.从经验来看,我发现这种结构更容易出错.例如,假设您需要在函数开始时获取锁,现在您需要释放它 n 次.其他人可能不同意.

If you use autocb, which isn't my favorite ICS feature, then the compiler will call the autocb for you whenever you return/short-circuit out of the function. I find this construction to be more error-prone from experience. For instance, imagine you needed to acquire a lock at the start of the function, now you need to release it n times. Others might disagree.

另一个注释,在下面的评论中指出.autocb 的工作方式与 return 类似,因为它只接受一个值.如果你想像这个例子一样返回多个值,你需要返回一个数组或字典.defer 做解构分配来帮助你:

One other note, pointed out below in the comments. autocb works like return in that it only accepts one value. If you want to return multiple values as in this example, you need to return an array or dictionary. defer does destructuring assignments to help you out here:

await my_fn defer [err, image]

这篇关于如何正确处理 IcedCoffeeScript 的错误?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆