파이썬 예외 메시지 캡처


520
import ftplib
import urllib2
import os
import logging
logger = logging.getLogger('ftpuploader')
hdlr = logging.FileHandler('ftplog.log')
formatter = logging.Formatter('%(asctime)s %(levelname)s %(message)s')
hdlr.setFormatter(formatter)
logger.addHandler(hdlr)
logger.setLevel(logging.INFO)
FTPADDR = "some ftp address"

def upload_to_ftp(con, filepath):
    try:
        f = open(filepath,'rb')                # file to send
        con.storbinary('STOR '+ filepath, f)         # Send the file
        f.close()                                # Close file and FTP
        logger.info('File successfully uploaded to '+ FTPADDR)
    except, e:
        logger.error('Failed to upload to ftp: '+ str(e))

이것은 작동하지 않는 것 같습니다. 구문 오류가 발생합니다. 모든 종류의 예외를 파일에 기록하기 위해 이것을 수행하는 올바른 방법은 무엇입니까?


2
들여 쓰기가 깨졌습니다. 그리고 ,후를 생략하십시오 except.
Sven Marnach

3
당신은 생략하면 @SvenMarnach, ,후를 except, 당신은 얻을 것이다 global name 'e' is not defined더 나은 잘못된 구문 이하이다.
Val

12
@Val : Python 버전에 따라 except Exception as e또는 이어야 except Exception, e합니다.
Sven Marnach

1
아마도 8 개의 대답 주위에있을 수 있지만 파일을 열 때 닫기 부분은 try 문 안에 있어야하지 않지만 finally 문에 있거나 with 문으로 감싸 져 있어야합니다.
JC Rocamonde

답변:


733

포착하려는 예외 유형을 정의해야합니다. 따라서 일반적인 예외 except Exception, e:대신 except, e:기록하십시오 (어쨌든 기록됩니다).

다른 방법은 전체 시도 / 제외 코드를 다음과 같이 작성하는 것입니다.

try:
    with open(filepath,'rb') as f:
        con.storbinary('STOR '+ filepath, f)
    logger.info('File successfully uploaded to '+ FTPADDR)
except Exception, e: # work on python 2.x
    logger.error('Failed to upload to ftp: '+ str(e))

Python 3.x 및 최신 버전의 Python 2.x에서는 다음 except Exception as e대신 사용 합니다 except Exception, e.

try:
    with open(filepath,'rb') as f:
        con.storbinary('STOR '+ filepath, f)
    logger.info('File successfully uploaded to '+ FTPADDR)
except Exception as e: # work on python 3.x
    logger.error('Failed to upload to ftp: '+ str(e))

118
repr (e)는 예외 (및 메시지 문자열)를 제공합니다. str (e)는 메시지 문자열 만 제공합니다.
whitebeard

11
예외 로깅의 대안으로 logger.exception(e)대신 사용할 수 있습니다 . 동일한 logging.ERROR레벨 에서 추적으로 예외를 로그합니다 .
mbdevpl

1
@mbdevpl 이것은 사실이 아닌 것 같습니다. 예외에 STR ()를 호출하기 위해 나타납니다 ideone.com/OaCOpO
KevinOrr

6
except Exception, e:파이썬 3에서 구문 오류가 발생합니다. 이것이 예상됩니까?
Charlie Parker

27
Python3에서 @CharlieParker 쓰기except Exception as e:
eumiro

282

구문은 더 이상 파이썬 3에서 지원되지 않습니다. 대신 다음을 사용하십시오.

try:
    do_something()
except BaseException as e:
    logger.error('Failed to do something: ' + str(e))

2
실제로, 당신은 logger.error ( '무엇을하지 못했습니다 : % s', str (e))를 사용해야합니다. 그렇게하면, 당신의 로거 레벨이 에러보다 높으면 문자열 보간을하지 않습니다.
avyfain

7
@avyfain-잘못되었습니다. 명령문 logging.error('foo %s', str(e))은 항상 e문자열 로 변환 됩니다. 사후 관리를 위해 logging.error('foo %s', e)로깅 프레임 워크가 변환을 수행 할 수 있도록합니다.
Ron Dahlgren

1
python REPL (여기서는 Python 3.5.2 및 ipython 사용)에서 확인할 수 있습니다. 여기서 요점을 확인하십시오
Ron Dahlgren

2
예외 로깅의 대안으로 logger.exception(e)대신 사용할 수 있습니다 . 동일한 logging.ERROR레벨 에서 추적으로 예외를 로그합니다 .
mbdevpl

11
그주의 except BaseExceptionexcept Exception같은 수준에 있지 않습니다. except Exception파이썬 3에서는 작동하지만 KeyboardInterrupt예를 들어 잡을 수는 없지만 (코드를 중단하고 싶을 때 매우 편리합니다!) BaseException예외는 잡습니다. 예외 계층에 대해서는 이 링크 를 참조하십시오 .
jeannej 2016 년

41

이것을 로거를 위해 더 간단한 것으로 업데이트하십시오 (파이썬 2와 3 모두에서 작동합니다). 역 추적 모듈이 필요하지 않습니다.

import logging

logger = logging.Logger('catch_all')

def catchEverythingInLog():
    try:
        ... do something ...
    except Exception as e:
        logger.error(e, exc_info=True)
        ... exception handling ...

이것은 이제 오래된 방법입니다 (아직 작동하지만).

import sys, traceback

def catchEverything():
    try:
        ... some operation(s) ...
    except:
        exc_type, exc_value, exc_traceback = sys.exc_info()
        ... exception handling ...

exc_value는 오류 메시지입니다.


2
이것이 내가 선호하는 방법입니다. 문자열을 인쇄하면 로깅에 유용하지만 그 정보로 무엇이든 해야하는 경우 문자열 이상이 필요합니다.
sulimmesh

3
두 번째 예에서 '역 추적 가져 오기'가 필요하지 않습니까?
starikoff

35

e.message 또는 e.messages를 사용할 수있는 경우가 있지만 모든 경우에 작동하지는 않습니다. 어쨌든 str (e) 을 사용하는 것이 더 안전합니다

try:
  ...
except Exception as e:
  print(e.message)

42
이 문제는 당신이 경우, 예를 들어,하지 except Exception as eeIOError, 당신이 얻을 e.errno, e.filename그리고 e.strerror,하지만 분명히 더 e.message(파이썬에서 적어도 2.7.12). 오류 메시지를 캡처 str(e)하려면 다른 답변 에서처럼을 사용하십시오.
epalm

@epalm 예외 전에 IOError를 잡으면 어떻게됩니까?
Albert Thompson

@ HeribertoJuárez 왜 문자열로 캐스트 할 수있는 동안 특별한 경우를 잡을까요?
HosseyNJF

25

오류 클래스, 오류 메시지 및 스택 추적 (또는 그중 일부)을 원하면을 사용하십시오 sys.exec_info().

일부 형식의 최소 작업 코드 :

import sys
import traceback

try:
    ans = 1/0
except BaseException as ex:
    # Get current system exception
    ex_type, ex_value, ex_traceback = sys.exc_info()

    # Extract unformatter stack traces as tuples
    trace_back = traceback.extract_tb(ex_traceback)

    # Format stacktrace
    stack_trace = list()

    for trace in trace_back:
        stack_trace.append("File : %s , Line : %d, Func.Name : %s, Message : %s" % (trace[0], trace[1], trace[2], trace[3]))

    print("Exception type : %s " % ex_type.__name__)
    print("Exception message : %s" %ex_value)
    print("Stack trace : %s" %stack_trace)

다음과 같은 결과가 나타납니다.

Exception type : ZeroDivisionError
Exception message : division by zero
Stack trace : ['File : .\\test.py , Line : 5, Func.Name : <module>, Message : ans = 1/0']

sys.exc_info () 함수 는 가장 최근 예외에 대한 세부 사항을 제공합니다. 의 튜플을 반환합니다 (type, value, traceback).

traceback역 추적 객체의 인스턴스입니다. 제공된 방법으로 추적을 형식화 할 수 있습니다. 더 많은 것은 트레이스 백 문서 에서 찾을 수 있습니다 .


3
를 사용 e.__class__.__name__ 하면 예외 클래스도 반환 할 수 있습니다.
kenorb 2016 년

19

logger.exception("msg")트레이스 백으로 예외 로깅에 사용할 수 있습니다 .

try:
    #your code
except Exception as e:
    logger.exception('Failed: ' + str(e))

우연히도 클래스 e.msg의 문자열 표현입니다 Exception.
MarkHu

5
아니면 간단하게 logger.exception(e).
mbdevpl


5

BaseException 유형을 명시 적으로 지정할 수 있습니다. 그러나 이것은 BaseException의 파생물 만 포착합니다. 여기에는 모든 구현 제공 예외가 포함되지만 임의의 구식 클래스가 발생할 수도 있습니다.

try:
  do_something()
except BaseException, e:
  logger.error('Failed to do something: ' + str(e))


2

파이썬 3.8.2 (그리고 아마도 그 이전의 몇 가지 버전)에서 미래의 어려움을 겪는 사람들을 위해 구문은 다음과 같습니다.

except Attribute as e:
    print(e)

1

str(e)또는 사용repr(e) 을 하여 예외를 나타내면 실제 스택 추적을 얻지 못하므로 예외가있는 위치를 찾는 것이 도움이되지 않습니다.

다른 답변과 로깅 패키지 문서를 읽은 후 다음 두 가지 방법으로 디버깅이 용이하도록 실제 스택 추적을 인쇄 할 수 있습니다.

logger.debug()매개 변수와 함께 사용exc_info

try:
    # my code
exception SomeError as e:
    logger.debug(e, exc_info=True)

사용하다 logger.exception()

또는 logger.exception()예외를 인쇄하는 데 직접 사용할 수 있습니다 .

try:
    # my code
exception SomeError as e:
    logger.exception(e)
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.