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

kotlin 没有受检异常真太难顶了。吐槽

  •  
  •   jeesk · 80 天前 · 3743 次点击
    这是一个创建于 80 天前的主题,其中的信息可能已经有所发展或是发生改变。
    1. 比如我要统一处理登陆失败和网络错误。

    如果是在 java 里面直接在方法里面抛出 2 个异常即可。 但是在 kotlin 里面必须

    	val runResult = runCatching{
           HttpResponse(it.isSuccessful,it.code,it.message)
        }
        if(runResult.isFailure){
           when(moveFileAgain.exceptionOrNull()){
            // 单独处理异常
              
           }
        
        }
        // 还有写一些(这里请求成功了)
        if(result.code == 404){
           return runResult.getOrDefault()
        }
          if(result.code == 401){
            // 认证失败了
           return runResult.getOrDefault()
        }
       
    
    

    如果是在 java 里面就再简单不过了,直接定义两个异常,全局处理. 受检查异常是真的爽。 特别是在嵌套请求,1 个 api 要请求好几次的情况。

    这么说吧。 这里面的很多常见使用 java 来写代码可能要简单的多。 哪有这么多的破事。

    大佬们有什么办法处理这种事情, 我的要求就是登陆 401 或者有异常直接返回就是了。kotlin 实在是太繁琐了。

    42 条回复    2024-10-17 19:31:08 +08:00
    RicardoY
        1
    RicardoY  
       79 天前
    没有看懂这和受检异常的关系是什么,你用 kotlin 不一样可以抛出自定义异常吗
    winterbells
        2
    winterbells  
       79 天前 via Android
    同样看不懂你要什么

    val exception = Exception("401")

    if (xxx) throw exception
    zhwguest
        3
    zhwguest  
       79 天前
    我猜 op 的意思是在收到非 2xx 状态码的时候抛出异常。

    但是这个是 API 的特性,而不是语言的特性。比如 okhttp ,ktor 等。api 一般都有选项可以设置什么时候抛出异常,什么时候认为是正常的 response 。
    sagaxu
        4
    sagaxu  
       79 天前
    unchecked exception 和 checked exception ,唯一区别就是 unchecked 可以隐式想上传递,checked 必须包在 try 中或者在方法签名中显式声明。

    调用链路的上层,IDE 会提示哪些 checked exception 没有处理,而 unchecked exception 你无法知道可能会抛出哪些异常。所以 Kotlin 使用 @Throws(IOException::class)把信息包含进去。

    所以 OP 在 Kotlin 中同样可以“直接定义两个异常,全局处理”。但很遗憾,他用 runCatching 吃掉了异常,然后手动处理,把 Kotlin 写出了 Go 的感觉。
    superchijinpeng
        5
    superchijinpeng  
       79 天前   ❤️ 5
    有没有可能是你不会用
    hwb
        6
    hwb  
       79 天前
    有没有可能是你不会用
    chendy
        7
    chendy  
       79 天前
    看到标题:怎么会有人喜欢 Checked Exception 呢?
    看完内容:果然说的不是 Checked Exception

    代码封装或者风格的问题,和语言不能说毫无关系只能说毫无关系
    yuhuazhu
        8
    yuhuazhu  
       79 天前
    自己定义一个方法统一判断然后抛出异常,
    然后 BaseViewModel 的写一个协程的扩展函数去处理异常,
    比如你给这个函数起名字叫 runCatching
    Vaspike
        9
    Vaspike  
       79 天前
    java 能做的 kotlin 一定能做
    jeesk
        10
    jeesk  
    OP
       79 天前
    @Vaspike 能帮我强制处理异常不? 我嵌套 10 几个函数, 如果没有受检查异常, 每个都要单独判断. 处理工作量大幅增加. 现在只能将异常封装在函数返回值里面.
    location123
        11
    location123  
       79 天前
    使用 OkHttp 的情况下
    只是判断这个请求的 http 请求错误 可以判断异常父类是否是 HttpException
    inline fun <T : HttpService, R> T.execute(block: T.() -> BaseResponse<R>): Result<R> {
    return try {
    val response = block()
    if (response.success) {
    Result.Success(response.data)
    } else {
    //内置协议错误
    // Result.Fail(response.header.code.toInt(), response.header.msg, false)
    }
    } catch (e: HttpException) {
    //http fail
    } catch (e:CancellationException){
    //cancel
    } catch (e: Exception) {
    //other fail
    }
    }
    网络请求全部走 HttpService 的扩展函数

    第二种
    在协程的顶级作用域里面统一处理
    chendy
        12
    chendy  
       79 天前
    @jeesk 再封装一层,异常情况直接甩异常出来
    maninfog
        13
    maninfog  
       79 天前   ❤️ 1
    Java 能抛的异常,Kotlin 也能抛。只是说 Kotlin 对于 Checked Exception (CE) 没了编译器的保护,up 觉得不太安全?
    关于 Kotlin 取消 CE ,褒贬不一,想起这个文章: https://www.yinwang.org/blog-cn/2017/05/23/kotlin
    jeesk
        14
    jeesk  
    OP
       79 天前
    @chendy 目前就是用 runtrycatch 了, 如果有异常, 直接将异常回填到返回值了。
    jeesk
        15
    jeesk  
    OP
       79 天前
    @maninfog 某些情况下合理使用受检查异常, 能省下很多的代码。
    cmdOptionKana
        16
    cmdOptionKana  
       79 天前
    Checked Exception 与 Go 的 error 貌似有共通的思想。
    githmb
        17
    githmb  
       79 天前
    《提问的艺术》
    jeesk
        18
    jeesk  
    OP
       79 天前
    @githmb 我这不是吐槽吗?
    AoEiuV020JP
        19
    AoEiuV020JP  
       79 天前
    没懂,throw, try, catch, 哪个是 kotlin 办不到的,效果明明和 java 一样,
    你要不试试用 java 写了再一键转成 kotlin 看看再说有什么问题,
    yazinnnn0
        20
    yazinnnn0  
       79 天前
    这跟嗑特灵有啥关系
    githmb
        21
    githmb  
       79 天前
    @jeesk 吐槽也要吐槽对啊,什么叫”kotlin 里面必须“,然后贴一段排版差注释差的代码,不用 Result 风格不就行了? Kotlin 哪里不能抛异常了?
    qwwuyu
        22
    qwwuyu  
       79 天前
    @jeesk 受检查异常并不能能省下代码.最多是忘记捕获某个特定的异常,导致程序异常.
    yuezk
        23
    yuezk  
       79 天前
    感觉是用法问题,还在用 Java 的语言习惯来写 Kotlin
    Leviathann
        24
    Leviathann  
       79 天前
    use typed error
    niubilewodev
        25
    niubilewodev  
       79 天前
    看下来没看懂。
    kotlin 只是去掉了 checked exception 必须要显式处理的特性。
    该抛什么错还是一样会抛什么错。
    你在 java 怎么 catch 的,在 kotlin 一样能 catch 到。
    little_cup
        26
    little_cup  
       79 天前
    @githmb 我反而觉得题主很懂啊,你要是正儿八经提个问,回帖能有现在的零头不
    jeesk
        27
    jeesk  
    OP
       79 天前
    @niubilewodev 是能够 catch 到, 但不是受检异常, 如果忘了就嗝屁了.
    WebKit
        28
    WebKit  
       79 天前
    感觉是你不会用,或者是你编码习惯的问题。除了成功。其他都是异常情况,必须要处理异常情况,不存在忘记的情况
    superchijinpeng
        29
    superchijinpeng  
       79 天前
    @jeesk #27 为什么会忘记,测试肯定会覆盖到
    zed1018
        30
    zed1018  
       79 天前
    我反而讨厌 checked exception ,正常需要处理的肯定会 catch ,不需要处理的就像让他 throw 就完事了,遇到 checked 的还要 catch 以后转 runtime ,当然,我是后端有框架兜底策略。
    jeesk
        31
    jeesk  
    OP
       79 天前
    @superchijinpeng 你测试一定能测试出所有的 BUG.


    场景不一样, 我觉得很多人 get 不到我的点. 如果支持受检测异常, 异常处理只需要在调用处处理异常即可, 但是 kotlin 没有受检异常, 可能会漏掉. 难道我不知道 kotlin 一样能使用 try catch 吗?

    我说没有受检异常, 你跑来告诉我可以使用 try catch . 这是一个东西吗?
    然后我说使用 try catch 可能会漏掉, 然后你告诉我测试肯定会覆盖.
    unco020511
        32
    unco020511  
       79 天前
    这个是你真的不会用了,和语言无关啊
    superchijinpeng
        33
    superchijinpeng  
       79 天前
    @jeesk #31 你可能会忘,IDE 不会,.try 会自动帮你补全所有情况
    githmb
        34
    githmb  
       79 天前
    就问你一个问题,空指针异常是不是 Java 程序出问题最多的异常,为什么空指针异常要搞成运行时异常,让这么多人漏掉?
    jeesk
        35
    jeesk  
    OP
       79 天前
    @githmb 不想回答你. 能不能不要问牛答马 ?
    yooomu
        36
    yooomu  
       79 天前
    没看懂你的诉求,checked exception 和 unchecked 的唯一不同就是编译器强制你捕获它。所以是因为 kotlin 编译器没有强制你捕获让你没有安全感吗
    catamaran
        37
    catamaran  
       79 天前
    受检异常,这是谁起的名字,我第一次看到
    Mystery0
        38
    Mystery0  
       79 天前
    java 里面怎么全局处理?用
    ```
    Thread.setDefaultUncaughtExceptionHandler((t, e) -> {
    //fuck something
    });
    ```
    ?

    那 kt 也没阉割这个啊,kt 不照样可以写这个
    SoloCompany
        39
    SoloCompany  
       79 天前
    我来教你怎么在 java 里面像 kotlin 那样不用忍受反人类的 checked exception
    https://stackoverflow.com/questions/11584159/is-there-a-way-to-make-runnables-run-throw-an-exception/53456631#53456631
    wwalkingg
        40
    wwalkingg  
       79 天前
    1. 题主不熟悉 Kotlin
    2. 题主觉得想要语言强制要求处理受查对象。这个特性本身有争议。个人觉得 Kotlin 这样很好,反正最后有一个兜底的异常捕获就行。
    Belmode
        41
    Belmode  
       79 天前 via Android
    无力吐槽
    ChenFanlin
        42
    ChenFanlin  
       74 天前
    https://plugins.jetbrains.com/plugin/12673-csense--kotlin-checked-exceptions
    可以使用这个扩展把 checked-exceptions 的检查加回来
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   1344 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 24ms · UTC 17:30 · PVG 01:30 · LAX 09:30 · JFK 12:30
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.