Обработка исключений
Содержание:
- Raising Exceptions
- «Голое» исключение
- Ловите много конкретных исключений
- Conclusion
- Основные исключения
- try/except¶
- Summing Up
- Raising an Exception in Python
- Python Errors and Exceptions Refresher
- Попробуйте except или else
- 8.3. Handling Exceptions¶
- Базовая структура обработки исключений
- Не помещайте Конфиденциальные данные в Сообщения об исключениях
Raising Exceptions
We can use raise keyword to throw an exception from our code. Some of the possible scenarios are:
- Function input parameters validation fails
- Catching an exception and then throwing a custom exception
class ValidationError(Exception): pass def divide(x, y): try: if type(x) is not int: raise TypeError("Unsupported type") if type(y) is not int: raise TypeError("Unsupported type") except TypeError as e: print(e) raise ValidationError("Invalid type of arguments") if y is 0: raise ValidationError("We can't divide by 0.") try: divide(10, 0) except ValidationError as ve: print(ve) try: divide(10, "5") except ValidationError as ve: print(ve)
Output:
We can't divide by 0. Unsupported type Invalid type of arguments
«Голое» исключение
Есть еще один способ поймать ошибку:
Python
try:
1 / 0
except:
print(«You cannot divide by zero!»)
1 2 3 4 |
try 1 except print(«You cannot divide by zero!») |
Но мы его не рекомендуем. На жаргоне Пайтона, это известно как голое исключение, что означает, что будут найдены вообще все исключения. Причина, по которой так делать не рекомендуется, заключается в том, что вы не узнаете, что именно за исключение вы выловите. Когда у вас возникло что-то в духе ZeroDivisionError, вы хотите выявить фрагмент, в котором происходит деление на ноль. В коде, написанном выше, вы не можете указать, что именно вам нужно выявить. Давайте взглянем еще на несколько примеров:
Python
my_dict = {«a»:1, «b»:2, «c»:3}
try:
value = my_dict
except KeyError:
print(«That key does not exist!»)
1 2 3 4 5 6 |
my_dict={«a»1,»b»2,»c»3} try value=my_dict»d» exceptKeyError print(«That key does not exist!») |
Python
my_list =
try:
my_list
except IndexError:
print(«That index is not in the list!»)
1 2 3 4 5 6 |
my_list=1,2,3,4,5 try my_list6 exceptIndexError print(«That index is not in the list!») |
В первом примере, мы создали словарь из трех элементов. После этого, мы попытались открыть доступ ключу, которого в словаре нет. Так как ключ не в словаре, возникает KeyError, которую мы выявили. Второй пример показывает список, длина которого состоит из пяти объектов. Мы попытались взять седьмой объект из индекса.
Помните, что списки в Пайтоне начинаются с нуля, так что когда вы говорите 6, вы запрашиваете 7. В любом случае, в нашем списке только пять объектов, по этой причине возникает IndexError, которую мы выявили. Вы также можете выявить несколько ошибок за раз при помощи одного оператора. Для этого существует несколько различных способов. Давайте посмотрим:
Python
my_dict = {«a»:1, «b»:2, «c»:3}
try:
value = my_dict
except IndexError:
print(«This index does not exist!»)
except KeyError:
print(«This key is not in the dictionary!»)
except:
print(«Some other error occurred!»)
1 2 3 4 5 6 7 8 9 10 |
my_dict={«a»1,»b»2,»c»3} try value=my_dict»d» exceptIndexError print(«This index does not exist!») exceptKeyError print(«This key is not in the dictionary!») except print(«Some other error occurred!») |
Это самый стандартный способ выявить несколько исключений. Сначала мы попробовали открыть доступ к несуществующему ключу, которого нет в нашем словаре. При помощи try/except мы проверили код на наличие ошибки KeyError, которая находится во втором операторе except
Обратите внимание на то, что в конце кода у нас появилась «голое» исключение. Обычно, это не рекомендуется, но вы, возможно, будете сталкиваться с этим время от времени, так что лучше быть проинформированным об этом
Кстати, также обратите внимание на то, что вам не нужно использовать целый блок кода для обработки нескольких исключений. Обычно, целый блок используется для выявления одного единственного исключения. Изучим второй способ выявления нескольких исключений:
Python
try:
value = my_dict
except (IndexError, KeyError):
print(«An IndexError or KeyError occurred!»)
1 2 3 4 |
try value=my_dict»d» except(IndexError,KeyError) print(«An IndexError or KeyError occurred!») |
Обратите внимание на то, что в данном примере мы помещаем ошибки, которые мы хотим выявить, внутри круглых скобок. Проблема данного метода в том, что трудно сказать какая именно ошибка произошла, так что предыдущий пример, мы рекомендуем больше чем этот
Зачастую, когда происходит ошибка, вам нужно уведомить пользователя, при помощи сообщения.
В зависимости от сложности данной ошибки, вам может понадобиться выйти из программы. Иногда вам может понадобиться выполнить очистку, перед выходом из программы. Например, если вы открыли соединение с базой данных, вам нужно будет закрыть его, перед выходом из программы, или вы можете закончить с открытым соединением. Другой пример – закрытие дескриптора файла, к которому вы обращаетесь. Теперь нам нужно научиться убирать за собой. Это очень просто, если использовать оператор finally.
Ловите много конкретных исключений
Python — прекрасный язык-он невероятно популярен, имеет массу отличных ресурсов для обучения, имеет библиотеки для всего и может делать все, что угодно, от машинного обучения до аппаратного обеспечения до веб-разработки.
Возможно, именно поэтому вы решили изучать Python, но для многих мы выбрали Python, потому что верим в ценности Python. Если это звучит культово, то это потому, что так оно и есть. Перейдите к своему терминалу и запустите Python. Затем введите . Вы увидите манифест Python, 19 ( ) афоризмов языка Python, написанных его создателем Тимом Питерсом.
19 афоризмов в манифесте Python – “Дзен Питона” Тима Питерса
Это действительно имеет ценность помимо развлечений, поскольку дает представление о миссии Python и дает нам советы о том, как он должен был использоваться
Важной чертой в этом случае является:. “Ошибки никогда не должны проходить бесшумно
Если только явно не заставить замолчать.”
“Ошибки никогда не должны проходить бесшумно. Если только явно не заставить замолчать.”
Я надеюсь, что это было ясно изложено в вышеприведенных пунктах. Я прочитал это так: “Не ловите все исключения, если вы действительно этого не хотите, и часто ловите явные исключения.” Еще одна питоническая идиома в сообществе:
– Проси прощения, а не разрешения.”
Именно здесь Python резко отличается от традиционных парадигм C, Java и других традиционных языков. Способ Python обрабатывать процессы с исключениями-это просто пойти на это и обрабатывать исключения, если они возникают.
В C вы можете писать строки и строки кода, чтобы проверить наличие всех предварительных условий перед записью в файл — например, существует ли файл, есть ли у процесса разрешения на запись в файл и т. Д. Было бы плохой практикой не обращать внимания на все эти случаи и просто писать прямо в файл.
В Python все совсем наоборот. На самом деле, в некоторых случаях гораздо эффективнее сначала попробовать, а потом обрабатывать исключения. В приведенном выше примере, хотя вполне возможно, что права доступа к файлам неверны (или какая-то другая проблема), это крайний случай. В большинстве случаев вы будете писать в файл, который существует, и у вас есть разрешение на доступ, так зачем тратить ценную вычислительную мощность на проверку прав доступа к файлам?
Питонический способ справиться с этим заключается в том, чтобы обернуть запись в try-catch и перехватывать только конкретные исключения/крайние случаи, которые могут возникнуть, и обрабатывать их соответствующим образом. В большинстве случаев запись будет успешной, и любая логика в блоке catch будет полностью пропущена. В случае, если что-то пойдет не так, мы все равно справимся с этим.
Проверьте этот поток StackOverflow для еще нескольких примеров.
Эмпирическое правило: не тратьте слишком много времени на проверку предварительных условий, когда вместо этого вы можете предсказать и поймать конкретные исключения (т. Е. Попросить прощения, а не разрешения).
Conclusion
try…except blocks make it easy to debug your Python code. A program tries to run the code in a “try” block. If this fails, the “except” block runs. The code in a “finally” statement runs irrespective of whether an “except” block is executed.
In this tutorial, we have broken down how to use try…except blocks. We have discussed how to use else and except to customize your exception handling.
These blocks can be useful when you’re testing existing code or writing new code. It ensures that your program runs correctly and contains no errors.
For more Python learning resources, check out our comprehensive How to Learn Python guide.
Основные исключения
Вы уже сталкивались со множеством исключений. Ниже изложен список основных встроенных исключений (определение в документации к Пайтону):
- Exception – то, на чем фактически строятся все остальные ошибки;
- AttributeError – возникает, когда ссылка атрибута или присвоение не могут быть выполнены;
- IOError – возникает в том случае, когда операция I/O (такая как оператор вывода, встроенная функция open() или метод объекта-файла) не может быть выполнена, по связанной с I/O причине: «файл не найден», или «диск заполнен», иными словами.
- ImportError – возникает, когда оператор import не может найти определение модуля, или когда оператор не может найти имя файла, который должен быть импортирован;
- IndexError – возникает, когда индекс последовательности находится вне допустимого диапазона;
- KeyError – возникает, когда ключ сопоставления (dictionary key) не найден в наборе существующих ключей;
- KeyboardInterrupt – возникает, когда пользователь нажимает клавишу прерывания(обычно Delete или Ctrl+C);
- NameError – возникает, когда локальное или глобальное имя не найдено;
- OSError – возникает, когда функция получает связанную с системой ошибку;
- SyntaxError — возникает, когда синтаксическая ошибка встречается синтаксическим анализатором;
- TypeError – возникает, когда операция или функция применяется к объекту несоответствующего типа. Связанное значение представляет собой строку, в которой приводятся подробные сведения о несоответствии типов;
- ValueError – возникает, когда встроенная операция или функция получают аргумент, тип которого правильный, но неправильно значение, и ситуация не может описано более точно, как при возникновении IndexError;
- ZeroDivisionError – возникает, когда второй аргумент операции division или modulo равен нулю;
Существует много других исключений, но вы вряд ли будете сталкиваться с ними так же часто. В целом, если вы заинтересованы, вы можете узнать больше о них в документации Пайтон.
try/except¶
Если вы повторяли примеры, которые использовались ранее, то наверняка
были ситуации, когда выскакивала ошибка. Скорее всего, это была ошибка
синтаксиса, когда не хватало, например, двоеточия.
Как правило, Python довольно понятно реагирует на подобные ошибки, и их
можно исправить.
Тем не менее, даже если код синтаксически написан правильно, могут
возникать ошибки. В Python эти ошибки называются исключения (exceptions).
Примеры исключений:
In 1]: 2 ----------------------------------------------------- ZeroDivisionError division by zero In 2]: 'test' + 2 ----------------------------------------------------- TypeError must be str, not int
В данном случае возникло два исключения: ZeroDivisionError и
TypeError.
Чаще всего можно предсказать, какого рода исключения возникнут во время
исполнения программы.
Например, если программа на вход ожидает два числа, а на выходе выдает
их сумму, а пользователь ввел вместо одного из чисел строку, появится
ошибка TypeError, как в примере выше.
Python позволяет работать с исключениями. Их можно перехватывать и
выполнять определенные действия в том случае, если возникло исключение.
Примечание
Когда в программе возникает исключение, она сразу завершает работу.
Для работы с исключениями используется конструкция :
In 3]: try ... 2 ... except ZeroDivisionError ... print("You can't divide by zero") ... You can't divide by zero
Конструкция try работает таким образом:
- сначала выполняются выражения, которые записаны в блоке try
- если при выполнения блока try не возникло никаких исключений, блок except пропускается,
и выполняется дальнейший код - если во время выполнения блока try в каком-то месте возникло исключение,
оставшаяся часть блока try пропускается- если в блоке except указано исключение, которое возникло, выполняется код в блоке except
- если исключение, которое возникло, не указано в блоке except,
выполнение программы прерывается и выдается ошибка
Обратите внимание, что строка в блоке try не выводится:
In 4]: try ... print("Let's divide some numbers") ... 2 ... print('Cool!') ... except ZeroDivisionError ... print("You can't divide by zero") ... Let's divide some numbers You can't divide by zero
В конструкции try/except может быть много except, если нужны разные
действия в зависимости от типа ошибки.
Например, скрипт divide.py делит два числа введенных пользователем:
# -*- coding: utf-8 -*- try a = input("Введите первое число: ") b = input("Введите второе число: ") print("Результат: ", int(a)int(b)) except ValueError print("Пожалуйста, вводите только числа") except ZeroDivisionError print("На ноль делить нельзя")
Примеры выполнения скрипта:
$ python divide.py Введите первое число: 3 Введите второе число: 1 Результат: 3 $ python divide.py Введите первое число: 5 Введите второе число: 0 На ноль делить нельзя $ python divide.py Введите первое число: qewr Введите второе число: 3 Пожалуйста, вводите только числа
В данном случае исключение ValueError возникает, когда пользователь
ввел строку вместо числа, во время перевода строки в число.
Исключение ZeroDivisionError возникает в случае, если второе число было
равным 0.
Если нет необходимости выводить различные сообщения на ошибки ValueError
и ZeroDivisionError, можно сделать так (файл divide_ver2.py):
# -*- coding: utf-8 -*- try a = input("Введите первое число: ") b = input("Введите второе число: ") print("Результат: ", int(a)int(b)) except (ValueError, ZeroDivisionError): print("Что-то пошло не так...")
Проверка:
$ python divide_ver2.py Введите первое число: wer Введите второе число: 4 Что-то пошло не так... $ python divide_ver2.py Введите первое число: 5 Введите второе число: 0 Что-то пошло не так...
Summing Up
After seeing the difference between syntax errors and exceptions, you learned about various ways to raise, catch, and handle exceptions in Python. In this article, you saw the following options:
- allows you to throw an exception at any time.
- enables you to verify if a certain condition is met and throw an exception if it isn’t.
- In the clause, all statements are executed until an exception is encountered.
- is used to catch and handle the exception(s) that are encountered in the try clause.
- lets you code sections that should run only when no exceptions are encountered in the try clause.
- enables you to execute sections of code that should always run, with or without any previously encountered exceptions.
Free PDF Download: Python 3 Cheat Sheet
Raising an Exception in Python
We can use the raise to throw an exception if the condition occurs.
The statement can be complemented with the custom exception.
If you want to throw the error when the particular condition occurs using raise, you can write the code like below.
# app.py el = 11 if el > 10: raise Exception('el should not exceed 10. The value of x was: {}'.format(x))
See the output.
➜ pyt python3 app.py Traceback (most recent call last): File "app.py", line 3, in raise Exception('el should not exceed 10. The value of x was: {}'.format(x)) NameError: name 'x' is not defined ➜ pyt
The execution comes to a halt and displays our exception to screen, offering clues about what went wrong.
Python Errors and Exceptions Refresher
In Python, there are two kinds of errors you may encounter: syntax errors and exceptions.
Python syntax errors are a type of error that returns when you use the wrong syntax. For example, if you write a while True loop without a colon at the end, the program will report an error.
When syntax errors occur, they return the file name, line number, and an indicator of where an error may be present.
Exceptions are a type of error where code may have the right syntax but still contains a problem. There are many types of exception, but some of the most common you will encounter include: ArithmeticError, ImportError, ZeroDivisionError, NameError, and TypeError.
Попробуйте except или else
Оператор try/except также имеет пункт else. Он работает только в том случае, если в вашем коде нет ни единой ошибки. Давайте потратим немного времени и взглянем на парочку примеров:
Python
my_dict = {«a»:1, «b»:2, «c»:3}
try:
value = my_dict
except KeyError:
print(«A KeyError occurred!»)
else:
print(«No error occurred!»)
1 2 3 4 5 6 7 8 |
my_dict={«a»1,»b»2,»c»3} try value=my_dict»a» exceptKeyError print(«A KeyError occurred!») else print(«No error occurred!») |
Мы видим словарь, состоящий из трех элементов, и в операторе try/except мы открываем доступ к существующему ключу. Это работает, так что ошибка KeyError не возникает. Так как ошибки нет, else работает, и надпись“No error occurred!” появляется на экране. Теперь добавим оператор finally:
Python
my_dict = {«a»:1, «b»:2, «c»:3}
try:
value = my_dict
except KeyError:
print(«A KeyError occurred!»)
else:
print(«No error occurred!»)
finally:
print(«The finally statement ran!»)
1 2 3 4 5 6 7 8 9 10 |
my_dict={«a»1,»b»2,»c»3} try value=my_dict»a» exceptKeyError print(«A KeyError occurred!») else print(«No error occurred!») finally print(«The finally statement ran!») |
В данном коде работают и оператор else и finally. Большую часть времени вы не будете сталкиваться с оператором else, используемый в том или ином коде, который следует за оператором try/except, если ни одна ошибка не была найдена. Единственное полезное применение оператора else, которое я видел, это когда вы хотите запустить вторую часть кода, в которой может быть ошибка. Конечно, если ошибка возникает в else, то она не будет поймана.
8.3. Handling Exceptions¶
It is possible to write programs that handle selected exceptions. Look at the
following example, which asks the user for input until a valid integer has been
entered, but allows the user to interrupt the program (using Control-C or
whatever the operating system supports); note that a user-generated interruption
is signalled by raising the exception.
>>> while True ... try ... x = int(input("Please enter a number: ")) ... break ... except ValueError ... print("Oops! That was no valid number. Try again...") ...
The statement works as follows.
-
First, the try clause (the statement(s) between the and
keywords) is executed. -
If no exception occurs, the except clause is skipped and execution of the
statement is finished. -
If an exception occurs during execution of the try clause, the rest of the
clause is skipped. Then if its type matches the exception named after the
keyword, the except clause is executed, and then execution
continues after the statement. -
If an exception occurs which does not match the exception named in the except
clause, it is passed on to outer statements; if no handler is
found, it is an unhandled exception and execution stops with a message as
shown above.
A statement may have more than one except clause, to specify
handlers for different exceptions. At most one handler will be executed.
Handlers only handle exceptions that occur in the corresponding try clause, not
in other handlers of the same statement. An except clause may
name multiple exceptions as a parenthesized tuple, for example:
... except (RuntimeError, TypeError, NameError): ... pass
A class in an clause is compatible with an exception if it is
the same class or a base class thereof (but not the other way around — an
except clause listing a derived class is not compatible with a base class). For
example, the following code will print B, C, D in that order:
class B(Exception): pass class C(B): pass class D(C): pass for cls in B, C, D]: try raise cls() except D print("D") except C print("C") except B print("B")
Note that if the except clauses were reversed (with first), it
would have printed B, B, B — the first matching except clause is triggered.
The last except clause may omit the exception name(s), to serve as a wildcard.
Use this with extreme caution, since it is easy to mask a real programming error
in this way! It can also be used to print an error message and then re-raise
the exception (allowing a caller to handle the exception as well):
import sys try f = open('myfile.txt') s = f.readline() i = int(s.strip()) except OSError as err print("OS error: {0}".format(err)) except ValueError print("Could not convert data to an integer.") except print("Unexpected error:", sys.exc_info()[]) raise
The … statement has an optional else
clause, which, when present, must follow all except clauses. It is useful for
code that must be executed if the try clause does not raise an exception. For
example:
for arg in sys.argv1:]: try f = open(arg, 'r') except OSError print('cannot open', arg) else print(arg, 'has', len(f.readlines()), 'lines') f.close()
The use of the clause is better than adding additional code to
the clause because it avoids accidentally catching an exception
that wasn’t raised by the code being protected by the …
statement.
When an exception occurs, it may have an associated value, also known as the
exception’s argument. The presence and type of the argument depend on the
exception type.
The except clause may specify a variable after the exception name. The
variable is bound to an exception instance with the arguments stored in
. For convenience, the exception instance defines
so the arguments can be printed directly without having to
reference . One may also instantiate an exception first before
raising it and add any attributes to it as desired.
>>> try ... raise Exception('spam', 'eggs') ... except Exception as inst ... print(type(inst)) # the exception instance ... print(inst.args) # arguments stored in .args ... print(inst) # __str__ allows args to be printed directly, ... # but may be overridden in exception subclasses ... x, y = inst.args # unpack args ... print('x =', x) ... print('y =', y) ... <class 'Exception'> ('spam', 'eggs') ('spam', 'eggs') x = spam y = eggs
If an exception has arguments, they are printed as the last part (‘detail’) of
the message for unhandled exceptions.
Exception handlers don’t just handle exceptions if they occur immediately in the
try clause, but also if they occur inside functions that are called (even
indirectly) in the try clause. For example:
Базовая структура обработки исключений
В предыдущем разделе мы продемонстрировали, как возникает исключение и как с этим справиться. В этом разделе мы обсудим базовую структуру кодирования для обработки исключений. Таким образом, базовая структура кода для обработки исключений в Python приведена ниже.
name = 'Imtiaz Abedin' try: # Write the suspicious block of code print(name) except AssertionError: # Catch a single exception # This block will be executed if exception A is caught print('AssertionError') except (EnvironmentError, SyntaxError, NameError) as E: # catch multiple exception # This block will be executed if any of the exception B, C or D is caught print(E) except : print('Exception') # This block will be executed if any other exception other than A, B, C or D is caught else: # If no exception is caught, this block will be executed pass finally: # This block will be executed and it is a must! pass # this line is not related to the try-except block print('This will be printed.')
Здесь вы можете видеть, что мы используем ключевое слово except в другом стиле. Первое ключевое слово except используется для перехвата только одного исключения, а именно исключения AssertionError.
Однако, как видите, второе ключевое слово except используется для перехвата нескольких исключений.
Если вы используете ключевое слово except без упоминания какого-либо конкретного исключения, оно перехватит любое исключение, созданное программой.
Блок else будет выполнен, если не будет найдено исключение. Наконец, независимо от того, будет ли обнаружено какое-либо исключение, будет выполнен блок finally.
Итак, если вы запустите приведенный выше код, мы получим результат:
Если вы измените name на nameee в приведенном выше коде, вы получите следующий результат:
Не помещайте Конфиденциальные данные в Сообщения об исключениях
Мне нужна защищенная система, поэтому имеет смысл . (Не уверен, что это означает f? Ознакомьтесь с моей статьей об этом ).
Это хорошее исключение — понятно, что означает исключение, я предоставил ему достаточную информацию, и оно достаточно специфично, его можно было бы безопасно завернуть в try-catch и обрабатывать по-другому, если бы, например, мы были более расслаблены с паролями администратора, чем с пользователями.
Проблема здесь сводится к конфиденциальным данным. Я привел здесь несправедливый пример, поэтому я надеюсь, что для вас совершенно очевидно, что это не хорошее исключение. Это исключение будет извергать необработанные текстовые пароли через ваши журналы, в ответах, в ваше программное обеспечение для мониторинга и, возможно, в сомнительные руки.
Исключения для внутреннего использования (см
Примечание внизу об исключениях, связанных с клиентами) могут содержать технические детали, такие как или конкретные данные, которые вызвали сбой, но важно помнить, что при возникновении исключения эти сообщения будут распространяться повсюду, через программное обеспечение для ведения журнала, отчетности и мониторинга — и, если вы не будете осторожны, возможно, для ваших пользователей
Конечно, все это сводится к хорошему дизайну программного обеспечения, но в мире , где регулирование персональных данных постоянно ужесточается , вы никогда не можете быть слишком осторожны, и почти всегда можно предоставлять ценные сообщения об ошибках без ущерба для конфиденциальности клиентов.
Эмпирическое правило: Не используйте конфиденциальную информацию в сообщениях об исключениях.
Однако вам нужно беспокоиться не только о конфиденциальности клиентов. Плохие актеры повсюду.
пытаясь защитить данные ваших клиентов, защитите свои серверы от хакеров, создавая функции вовремя
Допустим, вы запускаете веб-сайт, на котором пользователи предоставляют большое количество, и вы вычисляете коэффициенты этого числа. Давайте назовем ваш сайт FactoriseMe.com .
Вы собираетесь увеличить свои инвестиции в посевные проекты, но на рынке появляется конкурент, NumbersWithinNumbers.com . Вы протестировали их продукт, и хотя он работает, он не так быстр, как ваш. И клиентский опыт намного хуже.
Один из ваших разработчиков замечает, что для очень больших чисел ваша серверная служба изо всех сил пытается вычислить коэффициенты-на самом деле, для очень, очень больших чисел служба тратит все 180 секунд на хруст чисел и просто тайм-аут.
Вы решаете продолжать улучшать свой клиентский опыт, отвечая приятной для клиента ошибкой: “Время ожидания калькулятора истекло во время вычисления коэффициентов. Извините, но эти трудные.”
Это здорово. Теперь клиент знает, почему на сайте не удалось найти какие-либо факторы. Вы заходите в свой инвестор, чтобы дать демо-версию, и вдруг ваш сайт не работает. Что случилось?
Просмотрев журналы, вы замечаете, что между 9 и 10 часами утра вы получили 1000 запросов с огромными номерами от IP-адреса, расположенного чуть дальше по дороге, недалеко от штаб-квартиры NumbersWithinNumbers. Эти запросы перегружали ваши серверные службы и приводили к сбою вашего веб-сайта. Как?
Ты показал свою слабость. Никогда не показывай свою слабость. Или, по крайней мере, никогда не раскрывайте пользователям слабые места во внутренней работе вашего программного обеспечения. Хакеры, конкуренты, тролли и интернет в целом полны людей, которые хотят сломать то, что вы построили. Да, вы должны давать своим пользователям отзывы о том, что происходит, но никогда, никогда не рассказывайте им о внутренней работе вашего программного обеспечения.
Эмпирическое правило: расскажите пользователю о том, что он может сделать, а не о том, что произошло.
Вы увидите, что это часто встречается во многих приложениях: “Пожалуйста, повторите попытку позже.” “Если это повторится, пожалуйста, свяжитесь со службой поддержки.” “Неизвестная ошибка — мы сожалеем, мы изучаем ее.”
Но сейчас все это уходит от темы, исключения, ориентированные на пользователя,-это совершенно новая банка червей. Просто не забудьте взять листок из рыцаря из книги Монти Пайтона и притвориться, что все в порядке .