Python例外メッセージのキャプチャ


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ます。
スヴェンマルナッハ、2011年

3
@SvenMarnach、,after を省略するとexcept、を取得しますがglobal name 'e' is not defined、これは間違った構文よりもはるかに優れています。
Val

12
@Val:Pythonのバージョンに応じて、except Exception as eまたはexcept Exception, eにする必要があります。
Sven Marnach 2013年

1
多分それはそれらの8つの答えのどこかにありますが、ファイルを開くとき、閉じる部分はtryステートメントの内部ではなく、finallyステートメントまたはwithステートメントでラップされているべきです。
JCロカモンデ2018

回答:


733

キャッチする例外のタイプを定義する必要があります。したがって、一般的な例外(とにかくログに記録される)のexcept Exception, e:代わりに書き込みexcept, e:ます。

その他の可能性は、try / exceptコード全体を次のように記述することです。

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)はメッセージ文字列のみを提供します。
白ひげ2016

11
例外を記録するlogger.exception(e)代わりに、代わりに使用できます。同じlogging.ERRORレベルのトレースバックで例外をログに記録します。
mbdevpl 2016

1
@mbdevplこれは本当ではないようです。それは例外でstr()を呼び出すようです:ideone.com/OaCOpO
KevinOrr

6
except Exception, e:Python 3で構文エラーをスローします。これは予想されますか?
チャーリーパーカー

27
@CharlieParker in Python3 writeexcept Exception as e:
eumiro

282

構文はpython 3ではサポートされなくなりました。代わりに以下を使用してください。

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

2
実際には、logger.error( 'Failed to do何か:%s'、str(e))を使用する必要があります。このようにして、ロガーレベルがエラーを超えている場合、文字列の補間を行いません。
avyfain 2016

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 ExceptionPython3では機能しますが、KeyboardInterruptたとえば、コードを中断できるようにしたい場合はBaseExceptionキャッチしませんが、例外はキャッチします。例外の階層については、このリンクを参照してください。
jeannej

41

これをロガーにとってよりシンプルなものに更新します(Python 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 2016年

3
2番目の例で「トレースバックをインポート」する必要はありませんよね?
starikoff 2018年

34

e.messageまたはe.messages ..を使用できる場合がありますが、すべての場合に機能するわけではありません。とにかく、より安全なのはstr(e)を使用することです

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

42
これの問題は、例えば、あなたがexcept Exception as eであり、である場合、あなたeは、、およびIOErrorを取得しますがe.errno、明らかにそうではありません(少なくともPython 2.7.12では)。エラーメッセージをキャプチャする場合は、他の回答と同様に、を使用します。e.filenamee.strerrore.messagestr(e)
epalm

@epalm例外の前にIOErrorをキャッチするとどうなりますか?
アルバートトンプソン

@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__ すると、例外クラスも返されます。
ケノーブ2018年

19

logger.exception("msg")トレースバックで例外のロギングに使用できます。

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

偶然にも、クラスe.msgの文字列表現ですException
MarkHu 2016

5
または単にlogger.exception(e)
mbdevpl


5

明示的にBaseExceptionタイプを指定してみてください。ただし、これはBaseExceptionの派生物のみをキャッチします。これには、実装によって提供されるすべての例外が含まれますが、任意の古いスタイルのクラスが発生する可能性もあります。

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


2

将来の闘争者のために、Python 3.8.2(およびその前のいくつかのバージョン)では、構文は次のとおりです

except Attribute as e:
    print(e)

1

str(e)またはrepr(e)を使用して例外を表すと、実際のスタックトレースを取得できないため、例外の場所を見つけることは役に立ちません。

他の回答とロギングパッケージドキュメントを読んだ後、次の2つの方法は、デバッグを容易にするために実際のスタックトレースを出力するのに最適です。

使用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.