简体   繁体   English

Python 3异常处理和捕获

[英]Python 3 exception handling and catching

I'm designing a workflow engine for a very specific task and I'm thinking about exception handling. 我正在为特定任务设计工作流引擎,并且正在考虑异常处理。

I've got a main process that calls a few functions. 我有一个调用一些函数的主要过程。 Most of those functions call other more specific functions and so on. 这些功能大多数都调用其他更具体的功能,依此类推。 There are a few libraries involved so there are a lot of specific errors that can occur. 其中涉及一些库,因此可能会发生许多特定的错误。 IOError, OSError, AuthenticationException ... IOError,OSError,AuthenticationException ...

I have to stop the workflow when an error occurs and log it so I can continue from that point when the error is resolved. 发生错误时,我必须停止工作流程并将其记录下来,以便在解决错误后可以继续进行。

Example of what I mean: 我的意思示例:

def workflow_runner():
    download_file()
    ...
    (more calls with their own exceptions)
    ...


def download_file():
    ftps = open_ftp_connection()
    ftps.get(filename)
    ...
    (more calls with their own exceptions)
    ...


def open_ftp_connection():
    ftps = ftplib.FTP_TLS()
    try:
        ftps.connect(domain, port)
        ftps.login(username, password)
    except ftplib.all_errors as e:
        print(e)
        raise
    return ftps

Your basic, run of the mill, modular functions. 您的基本运行,模块化功能。

My question is this: 我的问题是这样的:

What's considered the best way of doing top to bottom error handling in Python 3? 在Python 3中,什么被认为是进行自上而下的错误处理的最佳方法?

  • To raise every exception to the top and thus put "try except" over each function call up the stack? 要将每个异常置于顶部,然后在每个函数上放置“ try try”,以调用堆栈?
  • To handle every exception when it happens, log and raise and have no "try except" at the "top"? 要处理每个异常,请记录并引发并且在“顶部”没有“除”以外的其他内容?
  • Some better alternative? 一些更好的选择?

Would it be better to just finish and raise the error on the spot or catch it in the "download_file" and/or "workflow_runner" functions? 只是当场完成并引发错误,或者将其捕获在“ download_file”和/或“ workflow_runner”函数中会更好吗?

I ask because if I end up catching everything at the top I feel like I might end up with: 我问,因为如果我最终把所有事情都排在了首位,我觉得自己可能会结局:

except AError
except BError
...
except A4Error

It depends… You catch an exception at the point where you can do something about it. 这取决于…您在可以采取措施的地方发现了一个例外。 That differs between different functions and different exception types. 不同的功能和不同的异常类型之间有所不同。 A piece of code calls a subsystem (generically speaking any function), and it knows that subsystem may raise exception A , B or C . 一段代码称为子系统(通常来说是任何函数),并且知道子系统可能引发异常ABC It now needs to decide what exceptions it expects and/or what it can do about each one of them. 现在,它需要确定预期的异常情况和/或对每个异常情况可以采取的措施。 In the end it may decide to catch A and B exceptions, but it wouldn't make sense for it to catch C exceptions because it can't do anything about them. 最后,它可能决定捕获AB异常,但是捕获C异常对它没有意义,因为它无法对它们做任何事情。 This now means this piece of code may raise C exceptions, and its callers need to be aware of that and make the same kinds of decisions. 现在,这意味着这段代码可能引发C异常,并且其调用者需要意识到这一点并做出相同类型的决策。

So different exceptions are caught at different layers, as appropriate. 因此,适当时在不同的层捕获了不同的异常。

In more concrete terms, say you have some system which consists of some HTTP object which downloads some stuff from remote servers, some job manager which wrangles a bunch of these HTTP objects and stores their result in a database, and a top level coordinator that starts and stops the job managers. 具体来说,假设您有一个系统,该系统由一些HTTP对象组成,该HTTP对象从远程服务器上下载一些东西,一些作业管理器将这些HTTP对象打包,并将它们的结果存储在数据库中,并且顶层协调器启动并停止工作经理。 The HTTP objects may obviously raise all sorts of HTTP exceptions when network requests fail, and the job managers may raise exceptions when something's wrong with the database. 当网络请求失败时,HTTP对象显然会引发各种HTTP异常,而当数据库出现问题时,作业管理器可能会引发异常。 You will probably let the job managers worry about HTTP errors like 404 , but not about something fundamental like ComputerDoesntHaveANetworkInterface errors; 您可能会让工作经理担心HTTP错误(例如404 ,而不是担心诸如ComputerDoesntHaveANetworkInterface错误之类的基本问题; equally DatabaseIsUnreachable exceptions is nothing a job manager can do anything about, and should probably lead to the termination of the application. 同样, DatabaseIsUnreachable异常是作业管理者无法做的任何事情,并且可能导致应用程序终止。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM