簡體   English   中英

為什么在 except 塊中發生異常時,finally 塊不返回最新的異常?

[英]Why doesn't finally block return the latest exception when an exception occurs within an except block?

我寫了一段代碼,我使用回溯來返回異常堆棧跟蹤。 但是我忘了導入回溯。

文件名 - trial_main.py

from fastapi import FastAPI
from pydantic import BaseModel
import uvicorn


app = FastAPI()

class RequestJson(BaseModel):
    data: str


@app.post("/trial", status_code=200)
async def trial(req:RequestJson):
    try:
        status = "default"
        resp = {
            "status": status,
            "reason": "default reason"
        }
        
        # error point
        a = 10/0
        
        status = "complete"
        reason = "Finished converting from base64 to image"
        
        resp = {
            "status": status,
            "reason": reason
        }
    except Exception as e:
        status = "incomplete"
        resp =  {
            "status": status,
            "reason": traceback.format_exc(),
        }
    finally:
        return resp


if __name__ == '__main__':
    uvicorn.run("trial_main:app", host="0.0.0.0", port=5001, log_level="info")

令我困惑的是,由於找不到回溯模塊,為什么代碼沒有以異常退出。 而是返回之前設置的默認響應。

這是我得到的 API 響應 -

{
    "status": "default",
    "reason": "default reason"
}

這是我運行 uvicorn 服務器的終端上的 output -

INFO:     Started server process [14744]
INFO:     Waiting for application startup.
INFO:     Application startup complete.
INFO:     Uvicorn running on http://0.0.0.0:5001 (Press CTRL+C to quit)
INFO:     127.0.0.1:61809 - "POST /trial HTTP/1.1" 200 OK

Api 端點 -

[POST] http://127.0.0.1:5001/trial

輸入重新創建情況 -

{"data": "randomString"}

這里沒有發生任何神秘事件。

在 try 塊中,您成功地為resp變量賦值,然后引發異常並執行到 except 塊。 您正在嘗試為resp分配新值,但 ImportError 發生在語句的右側,因此resp仍然包含舊值,該值將在 finally 塊中返回。 異常不會進一步傳播,因為 finally 塊中有return ,它只是抑制異常。

為了不被 fastapi 樣板分散注意力,所有這些都可以用更簡單的例子來說明

def always_return():
    """return 1"""
    try:
        res = 1
        raise Exception()
    except Exception:
        res = 1 / 0
    finally:
        return res


def never_return():
    """raises ZeroDivisionError"""

    try:
        res = 1
        raise Exception()
    except Exception:
        res = 1 / 0
    finally:
        print("finally block exists, but no return here")
    return res
>>> print(always_return())
1
>>> print(never_return())
finally block exists, but no return here
ZeroDivisionError: division by zero... traceback

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM