【问题标题】:Unable to catch exception being thrown from another function无法捕获从另一个函数抛出的异常
【发布时间】:2026-02-02 09:25:01
【问题描述】:

当服务器弹出错误代码 403 时,我期望 ServerHandler 中的“throw RuntimeException”继续执行 registerAccount 中的 catch 块,但我无法捕获错误...以下是我的代码:

LoginRepo.kt:

private fun registerAccount(context: Context, jsonObject: JSONObject, username: String, password: String): Result<LoggedInUser> {

    try {
        ServerHandler.getInstance(context).makeHttpRequest(
            "http://www.mywebpage.com/index.php",
            Request.Method.POST,
            jsonObject
        )

        return Result.Success(LoggedInUser(java.util.UUID.randomUUID().toString(), username))
    } catch (e: Throwable) {
        return Result.Error(IOException("Error registering account: ", e))
    }
}

ServerHandler.kt:

    @Throws(RuntimeException::class)
    fun makeHttpRequest(url: String, method: Int, jsonBody: JSONObject? = null):Any {
        // Instantiate the RequestQueue.
        Log.d("makeHttpRequest","Sending request!!!!")
        var stringRequest = when (method) {
            Request.Method.POST ->
                object : StringRequest(method, url,
                    Response.Listener<String> { response ->
                        Log.d("requestPOST", response)
                    }, Response.ErrorListener { error ->
                        @Throws(RuntimeException::class)
                        when(error.networkResponse.statusCode) {
                            403 -> {
                                throw RuntimeException("Username is taken.") //<--RuntimeException
                            }
                            else-> {
                                Log.d("UNHANDLED ERROR:", error.toString())
                            }
                        }})
                    }
       }

错误:

java.lang.RuntimeException: Username is taken.
    at com.example.inspire.data.ServerHandler$makeHttpRequest$stringRequest$5.onErrorResponse(ServerHandler.kt:75)

【问题讨论】:

    标签: rest android-studio exception kotlin android-volley


    【解决方案1】:

    我不知道所有细节,但似乎调用 ServerHandler.getInstance(context).makeHttpRequest( 必须立即返回(甚至在发出任何 HTTP 请求之前)。

    只需在调用之后、return 之前添加一个日志语句,看看是否真的如此。 HTTP 请求可能在稍后的某个时间点(可能在另一个线程中)发出,此时 registerAccount 函数已长时间但已退出(其中定义的 try/catch 块也是如此)。

    【讨论】:

    • 大声笑,我刚刚发现,你快了 16 秒哈哈,值得接受的答案。听起来像处理 Volley 的错误超出其范围是不可能的,因为 Volley 似乎没有像 JavaScript 那样提供 AJAX 回调函数/Promises。
    【解决方案2】:

    由于 Volley 回调中的异步特性,Android Studio 调试器帮助确认 registerAccount() 在 makeHttpRequest() 完成与 PHP 服务器通信的工作之前返回了结果。

    由于 registerAccount() 已经返回,makeHttpRequest() 中抛出的 RuntimeException("Username istake.") 已经没有人可以捕捉到它的异常,导致无法捕捉到异常。

    在这种情况下,捕获异常听起来是不可能的,所以我宁愿做一个 Toast.makeText( _语境, “用户名已存在!”, 吐司.LENGTH_LONG )。显示() 而不是抛出异常...

    【讨论】: