V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
FaiChou
V2EX  ›  程序员

你们喜欢 throw error 吗?

  •  
  •   FaiChou ·
    FaiChou · 2023-07-10 10:30:42 +08:00 · 1842 次点击
    这是一个创建于 510 天前的主题,其中的信息可能已经有所发展或是发生改变。

    平时普通的业务逻辑开发中,越来越不想 throw error 了,而是返回空。

    比如 swift 中:

    func req() async -> String? {
      if let foo = try? await SomeAsyncThrowsFunc() {
        return foo
      }
      return nil
    }
    
    用到的地方:
    
    Task {
      if let val = await req() {
        // get the string value
      } else {
        // somethings up
      }
    }
    

    下面是使用 throw 的版本:

    func req() async throws -> String {
        if let foo = try await SomeAsyncThrowsFunc() {
            return foo
        }
    }
    
    用到的地方:
    
    Task {
      do {
          let val = try await req()
          // get the string value
      } catch {
          // catch the error
      }
    }
    
    或者直接将错误转换成 Optional 赋值:
    if let val = try? await req() {}
    

    平时的业务逻辑没有写的那么完美,如果是写一个标准的库,定义所有的错误类型,遇到情况不对,throw 相对应的错误。但是到业务逻辑调用,函数包裹的越多,可能在中间一层将错误给抹掉,后面再也拿不到正确的错误值了。

    所以要想要规范,必须从头到尾规范起来,中间不能有松懈。但是,要偷懒,真的爽。(也承认自己写的不规范)

    fgwmlhdkkkw
        1
    fgwmlhdkkkw  
       2023-07-10 10:35:26 +08:00 via Android
    服务端不一样,有些功能是依赖异常的。比如事务的完全处理。
    zoharSoul
        2
    zoharSoul  
       2023-07-10 10:36:46 +08:00
    最外层统一捕获返回给前端/客户端就 ok 了
    TWorldIsNButThis
        3
    TWorldIsNButThis  
       2023-07-10 10:40:39 +08:00
    我现在倾向于返回 result ,用的地方指定是 throw 还是 null
    当然不是 swift
    FaiChou
        4
    FaiChou  
    OP
       2023-07-10 10:41:59 +08:00
    @TWorldIsNButThis 对的,Swift 只是个例子,其他语言比如 js 也可以这样做,返回空,用到时候判断是否为空,这样写起来比 try catch 省一些代码量。
    yazinnnn
        5
    yazinnnn  
       2023-07-10 10:42:18 +08:00
    你 throw 完了自己处理跟不 throw 有啥区别....

    throw 的前提当然是上一层的调用栈有统一的异常管理
    cheng6563
        6
    cheng6563  
       2023-07-10 10:55:15 +08:00
    用 go 吧,没有 throw 功能,每次都是直接返回 err ,你自己判断处理就是了。
    suyuyu
        7
    suyuyu  
       2023-07-10 11:21:07 +08:00
    我还以为你要说 js
    matepi
        8
    matepi  
       2023-07-10 11:23:51 +08:00   ❤️ 3
    throw 真正的意义是消息传递,return null 是函数返回
    为啥会对等起来比呢…
    sampeng
        9
    sampeng  
       2023-07-10 11:29:24 +08:00
    我比较倾向这个懒不能偷。写时一时爽,排查火葬场
    potatowish
        10
    potatowish  
       2023-07-10 11:42:00 +08:00 via iPhone   ❤️ 1
    返回空说明是正常的业务逻辑,throw error 是业务流程异常,你为啥会把这俩对等?
    lanlanye
        11
    lanlanye  
       2023-07-10 12:26:34 +08:00
    空值和异常不能对等,这是两种完全不同的东西。

    如果单论异常处理的话,有传统的 try...catch...方法,也有 Go 语言那种多返回值的方法。根据我个人的使用经验,前一种就非常好用,问题是可能会忘记处理,后一种的话需要语言支持自动把异常抛回上一层(比如 Rust ),否则代码写起来非常坐牢。
    Masoud2023
        12
    Masoud2023  
       2023-07-10 13:41:24 +08:00
    你不好好处理异常,到时候异常就来处理你,到时候调用栈摞的高了,出问题你只能看到一个空返回值的时候你就知道错了。
    Building
        13
    Building  
       2023-07-10 13:49:57 +08:00 via iPhone
    try catch 总感觉像上个世纪的用法
    现代用法:Result<Success, Error>
    thetbw
        14
    thetbw  
       2023-07-10 14:22:38 +08:00
    throw 可以中断后续的代码执行,不然你只能每个地方每个方法调用都是
    if result == null
    return null //or return error
    写一堆判断,就像 go 那种,看着就烦
    StoneHuLu
        15
    StoneHuLu  
       2023-07-10 15:38:44 +08:00
    你 return null 不抛异常带来的结果就是:菜鸡同事调你方法没判 null ,然后上线之后日志里面只有个 null point exception 。到时候查都不好查,throw exception 的好处是你可以定一下异常信息,日志里起码能看到,能抛异常就抛异常,别把异常当成 null 值处理,万一别人翻不了你源码,直接引用你 dll 文件或者类库,你让调用你的人怎么办,现去翻你文档还是直接找你问为啥?
    nuk
        16
    nuk  
       2023-07-10 18:55:39 +08:00
    我不光不 throw ,还要 catch 内部错误不处理,假装一切正常,有问题肯定是别人的问题,我这里都正常。
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   907 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 26ms · UTC 20:52 · PVG 04:52 · LAX 12:52 · JFK 15:52
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.