즉시 다시 발생하지 않으면 예외 추적이 숨겨집니다.
다음과 유사한 코드가 있습니다.
import sys
def func1():
func2()
def func2():
raise Exception('test error')
def main():
err = None
try:
func1()
except:
err = sys.exc_info()[1]
pass
# some extra processing, involving checking err details (if err is not None)
# need to re-raise err so caller can do its own handling
if err:
raise err
if __name__ == '__main__':
main()
때 func2
나는 다음 역 추적을받을 예외가 발생 :
Traceback (most recent call last):
File "err_test.py", line 25, in <module>
main()
File "err_test.py", line 22, in main
raise err
Exception: test error
여기에서 예외가 어디에서 오는지 알 수 없습니다. 원래 트레이스 백이 손실됩니다.
원래 트레이스 백을 보존하고 다시 올릴 수있는 방법은 무엇입니까? 다음과 비슷한 것을보고 싶습니다.
Traceback (most recent call last):
File "err_test.py", line 26, in <module>
main()
File "err_test.py", line 13, in main
func1()
File "err_test.py", line 4, in func1
func2()
File "err_test.py", line 7, in func2
raise Exception('test error')
Exception: test error
공백 raise
은 마지막 예외를 발생시킵니다.
# need to re-raise err so caller can do its own handling
if err:
raise
raise something
Python 을 사용 something
하는 경우 방금 전에 포착 된 예외 인지 또는 새 스택 추적이있는 새로운 예외 인지 알 수있는 방법이 없습니다 . 이것이 raise
스택 추적을 유지하는 공백이있는 이유 입니다.
예외 를 수정하고 다시 던질 수 있습니다.
표현식이 없으면
raise
현재 범위에서 활성화 된 마지막 예외를 다시 발생시킵니다. 현재 범위에서 예외가 활성화되지 않은 경우TypeError
오류임을 나타내는 예외가 발생합니다 (IDLE에서 실행중인 경우Queue.Empty
예외가 대신 발생 함).그렇지 않으면 생략 된 표현식의 값으로
raise
사용하여 세 개의 객체를 얻기 위해 표현식을 평가합니다None
. 처음 두 개체는 예외의 유형과 값을 결정하는 데 사용됩니다.세 번째 개체가 존재하고는 없으면
None
역 추적 개체 여야하며 (표준 유형 계층 구조 섹션 참조) 예외가 발생한 위치로 현재 위치 대신 대체됩니다. 세 번째 개체가 있고 역 추적 개체 또는가 아닌None
경우TypeError
예외가 발생합니다.의 three-expression 형식은 절
raise
에서 예외를 투명하게 다시 발생시키는 데 유용except
하지만raise
다시 발생시킬 예외가 현재 범위에서 가장 최근에 활성화 된 예외 인 경우에는 표현식이없는 것이 좋습니다.
따라서 예외를 수정하고 다시 발생 시키려면 다음과 같이 할 수 있습니다.
try:
buggy_code_which_throws_exception()
except Exception as e:
raise Exception, "The code is buggy: %s" % e, sys.exc_info()[2]
traceback 모듈 sys.exc_info()
과 함께 예외에 대한 많은 정보를 얻을 수 있습니다.
코드에 다음 확장을 시도하십시오.
import sys
import traceback
def func1():
func2()
def func2():
raise Exception('test error')
def main():
try:
func1()
except:
exc_type, exc_value, exc_traceback = sys.exc_info()
# Do your verification using exc_value and exc_traceback
print "*** print_exception:"
traceback.print_exception(exc_type, exc_value, exc_traceback,
limit=3, file=sys.stdout)
if __name__ == '__main__':
main()
이것은 당신이 원하는 것과 비슷하게 인쇄 될 것입니다.
*** print_exception:
Traceback (most recent call last):
File "err_test.py", line 14, in main
func1()
File "err_test.py", line 5, in func1
func2()
File "err_test.py", line 8, in func2
raise Exception('test error')
Exception: test error
While @Jochen's answer works well in the simple case, it is not capable of handling more complex cases, where you are not directly catching and rethrowing, but are for some reason given the exception as an object and wish to re-throw in a completely new context (i.e. if you need to handle it in a different process).
In this case, I propose the following:
- get the original exc_info
- format the original error message, with stack trace
- throw a new exception with that full error message (stack trace incl.) embedded
Before you do this, define a new exception type that you will rethrow later...
class ChildTaskException(Exception):
pass
In the offending code...
import sys
import traceback
try:
# do something dangerous
except:
error_type, error, tb = sys.exc_info()
error_lines = traceback.format_exception(error_type, error, tb)
error_msg = ''.join(error_lines)
# for example, if you are doing multiprocessing, you might want to send this to another process via a pipe
connection.send(error_msg)
Rethrow...
# again, a multiprocessing example of receiving that message through a pipe
error_msg = pcon.recv()
raise ChildTaskException(error_msg)
Your main function needs to look like this:
def main():
try:
func1()
except Exception, err:
# error processing
raise
This is the standard way of handling (and re-raising) errors. Here is a codepad demonstration.
'programing' 카테고리의 다른 글
ui-router 및 Angularjs를 사용하여 TOP으로 자동 스크롤 (0) | 2020.11.16 |
---|---|
Python 생성기에서 한 요소 (peek)를 미리 보는 방법은 무엇입니까? (0) | 2020.11.16 |
jquery AJAX 성공 콜백에서 함수에 변수 전달 (0) | 2020.11.16 |
Angular2-구성 요소로드시 텍스트 상자 집중 (0) | 2020.11.16 |
Google의 색인 생성 중지 (0) | 2020.11.16 |