python

时间:2018-03-19 14:02:10

标签: python python-3.x exception-handling

我的应用程序使用第三方API,它会抛出属于另一个api处理模块的异常。代码看起来像这样:

#API Module
def getdatafromapi(req):
    # Trying to get data ...
    if response_err in data:
        raise APIModuleException('API error')
    if conn_err in data:
        raise APIConnectionError('API error')

    # Do some processing
    return response
# My Module
def get_data_and_crunch(req):
    response = getdatafromapi(req)
    if not response:
        raise ValueError('Something happened')
    # Proceed to number crunch


# Main script
def main():
    # Sanitize api request...
    try:
        get_data_and_crunch(req)
    except ValueError:
       print('Something happened')

无论是APIModuleException还是APIConnectionError,主模块的行为方式都相同,但我仍然想记录哪个异常类实际导致异常。

有没有办法可以避免在我的主脚本中使用APIModuleExceptionAPIConnectionError类,并且仍然使用ValueError传播异常,以告诉哪个异常类实际导致了异常API模块?

2 个答案:

答案 0 :(得分:2)

确保模块的异常与API的类型不完全相同。它可以是基类型,因为ValueError似乎在您的情况下。在这方面你的提高代码是好的。

添加多个except块以捕获不同类型的异常:

try:
    get_data_and_crunch()
except (APIModuleException, APIConnectionError) as e:
    print('API error caught:', str(e))
except ValueError as e:
    print('My module!:', str(e))

您可以拥有任意数量的except块,并且每个块都可以捕获尽可能多的类型的异常。

如果ValueErrorValueError继承,那么将instanceof catch放在API异常之后是非常重要的。使用ValueError按顺序评估这些块,因此如果as ...块首先出现,则所有异常都会触发它,并且您永远不会看到特定于API的消息。

如果您需要了解有关异常的任意特定信息,请使用上面显示的ValueError语法提供的异常对象。函数sys.exc_info还可以帮助您获取导致错误的调用序列之类的信息。您可以使用traceback模块获取更多详细信息。

<强>更新

根据您的最新评论,您希望获得异常信息,而无需额外导入。 免责声明:这在技术上是可行的,我将在下面解释一种方法,但我高度建议采用这种方法。

诀窍是捕获您将获得的所有可能异常的基类,就像您尝试使用try: get_data_and_crunch() except Exception as e: print('Got a', type(e).__name__) 一样。问题在于,ValueError尽管是最广泛使用的异常类型之一,但不是所有异常的基础,Exception是。BaseException。你可以过火并抓住completeness,但是按 Ctrl + C 之类的东西会停止工作,所以不要这样做(只需要提及@abarnert's comment)。 / p>

您可以使用我在上面显示的相同符号来获取类型(以及类型的名称)。回溯也将照常工作,以显示调用序列和发生异常的位置:

sys.exc_info

根据{{3}},在您深入研究tracebacktype(e)之前,有一些常见的获取基本异常信息的方法。 str(e)将为您提供抛出错误的类。 repr(e)只返回99%的理智异常类中的错误消息。 type: message通常会返回您在打印输出结束时看到的标准... DO IT = 2,ITMAX DO I = 1,IMAX PHIN(IT-1,I,1) = PHIN(IT-1,I,2) - (Y(2) - Y(1))*UINF*PHIY(I) END DO PHIN(IT,I,1) = PHIN(IT-1,I,1) DO J = 2,JMAX-1 DO I = 2,IMAX-1 LPHI(I,J) = AX(I)*PHIN(IT-1,I-1,J) - & BX(I)*PHIN(IT-1,I,J) + & CX(I)*PHIN(IT-1,I+1,J) + & AY(J)*PHIN(IT-1,I,J-1) - & BY(J)*PHIN(IT-1,I,J) + & CY(J)*PHIN(IT-1,I,J+1) ENDDO ENDDO ! ! SELECT CASE(SOL) ! CASE(1) ! CALL NPJ() ! CASE(2) ! CALL NPGS() ! CASE(3) ! CALL NSOR() ! END SELECT DO J = 2,JMAX-1 DO I = 2,IMAX-1 C(I,J) = 1/(2*(DELTAX(I)**2 + DELTAY(J)**2))* & (((DELTAX(I)*DELTAY(J))**2)*LPHI(I,J) + & (PHIN(IT,I-1,J) - PHIN(IT-1,I-1,J))*DELTAY(J) + & (PHIN(IT,I,J-1) - PHIN(IT-1,I,J-1))*DELTAX(I)) END DO END DO PHIN(IT,:,:) = PHIN(IT-1,:,:) + C(:,:) RESI(IT) = MAXVAL(ABS(LPHI(:,:))) IF (RESI(IT)<EPS) THEN ITVALUE = IT EXIT ENDIF LPHI(:,:) = 0 WRITE(*,*) IT,RESI(IT) ENDDO ... 字符串。

作为免责声明的免责声明,我必须补充一点,虽然这样的技术不是推荐,但如果您知道自己在做什么,它们可以非常有效地使用。因此,请仔细阅读我链接的文档,并确保您彻底理解您的代码。这比听取任何通用的不合格警告要重要得多。

答案 1 :(得分:0)

我不确定我是否正确理解。但这将是区分异常的标准方法:

arrays