2016-07-26 7 views
1

Я хотел бы использовать raise без печати трассировки на экране. Я знаю, как это сделать, используя try ..catch, но не нашел способ с raise.Получение ошибок без следа

Вот пример:

def my_function(self): 
    resp = self.resp 
    if resp.status_code == 404: 
     raise NoSuchElementError('GET'+self.url+'{}'.format(resp.status_code)) 
    elif resp.status_code == 500: 
     raise ServerErrorError('GET'+self.url+'{}'.format(resp.status_code)) 

При выполнении этого, если у меня есть 404, то отслеживающий будет печатать на экране.

Traceback (most recent call last): 
    File "test.py", line 32, in <module> 
    print ins.my_function() 
    File "api.py", line 820, in my_function 
    raise NoSuchElementError('GET ' + self.url + ' {} '.format(resp.status_code)) 

Это API обертка, и я не хочу видеть отслеживающие пользователей, но чтобы увидеть коды ответов API и сообщения об ошибках вместо этого.

Есть ли способ сделать это?

+0

Форматирование отображения не является задачей 'raise'. Если вы хотите контролировать, как программа реагирует на эти исключения, поймайте их на каком-то более высоком уровне в структуре вашей программы и сделайте то, что будете с ними. – user2357112

ответ

2

Проблема заключается не в повышении чего-либо, а в том, что делает интерпретатор python, когда ваша программа завершается с исключением (и она просто печатает трассировку стека). Что нужно делать, если вы хотите, чтобы избежать этого, это поставить попробовать, за исключением блока вокруг всего, что вы хотите, чтобы «скрыть» трассировки стека, как:

def main(): 
    try: 
    actual_code() 
    except Exception as e: 
    print(e) 

Другой путь заключается в изменении обработчика Exeption, sys.excepthook(type, value, traceback), чтобы сделать свою собственную логику, как

def my_exchandler(type, value, traceback): 
    print(value) 

import sys 
sys.excepthook = my_exchandler 

вы можете даже условие исключения type и сделать определенную логику тогда и только тогда это ваш тип исключения, а в противном случае - потери мощности к оригиналу.

1

Поймайте исключение, запишите его и верните что-то, что указывает на то, что что-то пошло не так для потребителя (отправка 200 обратно, когда запрос не удался, скорее всего вызовет проблемы для вашего клиента).

try: 
    return do_something() 
except NoSuchElementError as e: 
    logger.error(e) 
    return error_response() 

Поддельный error_response() функция может сделать что-нибудь форма возвращения пустой ответ или сообщение об ошибке. Вы все равно должны использовать правильные коды состояния HTTP. Похоже, вы должны вернуть 404 в этом случае.

Вы должны обрабатывать исключения изящно, но вы не должны полностью скрывать ошибки от клиентов. В случае вашего исключения NoSuchElementError это звучит так, как будто клиент должен быть проинформирован (ошибка может быть на их конце).

1

Я столкнулся с аналогичной проблемой, когда родительский класс использовал значение исключения на raise для передачи сообщений, но там, где я не хотел сбрасывать трассировку. @lejlot дает отличное решение, используя sys.excepthook, но мне нужно было применить его с более ограниченными возможностями. Вот модификация:

import sys 
from contextlib import contextmanager 

@contextmanager 
def except_handler(exc_handler): 
    "Sets a custom exception handler for the scope of a 'with' block." 
    sys.excepthook = exc_handler 
    yield 
    sys.excepthook = sys.__excepthook__ 

Затем, чтобы использовать его:

def my_exchandler(type, value, traceback): 
    print(': '.join([str(type.__name__), str(value)])) 

with except_handler(my_exchandler): 
    raise Exception('Exceptional!') 

# -> Exception: Exceptional! 

Таким образом, если исключение не вызывается в блоке, обработка исключений по умолчанию будет возобновлено для любых последующих исключений:

with except_handler(my_exchandler): 
    pass 

raise Exception('Ordinary...') 

# -> Traceback (most recent call last): 
# -> File "raise_and_suppress_traceback.py", line 22, in <module> 
# ->  raise Exception('Ordinary...') 
# -> Exception: Ordinary...