Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
книги хакеры / Питер_Гудлиф_Ремесло_программиста_Практика_написания_хорошего_кода.pdf
Скачиваний:
16
Добавлен:
19.04.2024
Размер:
9.23 Mб
Скачать

 

 

 

 

hang

e

 

 

 

 

 

 

 

C

 

E

 

 

 

 

X

 

 

 

 

 

 

-

 

 

 

 

 

d

 

 

F

 

 

 

 

 

 

t

 

 

D

 

 

 

 

 

 

 

i

 

 

 

 

 

 

 

 

 

r

 

P

 

 

 

 

 

NOW!

o

 

 

 

 

 

 

 

 

 

 

 

 

 

BUY

 

 

 

 

 

 

to

 

 

 

 

 

w Click

 

 

 

Обработкаm

ошибок

 

 

 

 

w

 

 

 

 

 

 

 

 

 

 

w

 

 

 

 

 

 

 

o

 

 

.

 

 

 

 

 

.c

 

 

 

p

 

 

 

 

g

 

 

 

 

 

df

 

 

n

e

 

 

 

 

 

-xcha

 

 

 

 

 

 

 

 

hang

e

 

 

 

 

 

 

 

C

 

E

 

 

 

 

X

 

 

 

 

 

 

-

 

 

 

 

 

d

 

 

F

 

 

 

 

 

 

t

 

 

D

 

 

 

 

 

 

 

i

 

 

 

 

 

 

 

 

 

r

P

 

 

 

 

 

NOW!

o

 

 

 

 

 

 

 

 

 

 

 

 

BUY

 

 

 

 

 

 

to

 

 

 

 

 

143Click

 

 

 

 

 

m

 

 

 

 

 

 

w

 

 

 

 

 

 

 

o

 

 

w

 

 

 

 

 

 

 

 

w

 

 

 

 

 

 

.c

 

 

.

 

 

 

 

 

 

 

 

p

 

 

 

 

g

 

 

 

 

 

df

 

 

n

e

 

 

 

 

 

-x cha

 

 

 

 

безопасен в отношении исключений, или не делать ничего? Я предпо% читаю документировать режим обработки исключительных ситуаций.

Обработка ошибок

Люби истину, но будь снисходителен к заблуждениям.

Вольтер

Ошибки неизбежны. Мы видели, как их искать и когда это делать. Во% прос следующий: как с ними поступать? Ответить на него нелегко. В значительной мере ответ зависит от обстоятельств и тяжести ошиб% ки – можно ли исправить ситуацию и попробовать повторить опера% цию либо нужно двигаться дальше, несмотря ни на что. Часто такая возможность отсутствует: ошибка может свидетельствовать о начале агонии. Иногда лучше всего быстро навести порядок и завершить ра% боту, пока не стало еще хуже.

Такого рода решения принимаются при наличии достаточной инфор% мации. Есть ряд ключевых сведений, которые нужно знать об ошибке:

Где она возникла

Это совсем не то место, где она станет обрабатываться. Где находит% ся источник – в базовой системной компоненте или периферийном модуле? Эти данные могут присутствовать в сообщении об ошибке либо быть получены вручную.

Что вы пытались сделать?

Что спровоцировало ошибку? В этом может быть ключ ко всем вос% становительным действиям. В отчете об ошибке такие сведения встречаются редко, но по контексту можно выяснить, какая функ% ция была вызвана.

Почему возник сбой

В чем суть проблемы? Нужно точно узнать, что случилось, а не про% сто установить класс ошибки. Какая часть приведшей к ошибке операции успела выполниться? Прекрасно, если выполнилось все или ничего, но обычно программа оказывается в некоем промежу% точном состоянии.

Когда это случилось

Это локализация ошибки по времени. Произошел ли отказ только что или это проблема двухчасовой давности, известившая о себе только сейчас?

Степень тяжести ошибки

Одни проблемы опаснее других, хотя при обнаружении они все рав% нозначны – не разобравшись с проблемой и не найдя ее решения, нельзя двигаться дальше. Степень тяжести обычно определяет вы%

 

 

 

 

hang

e

 

 

 

 

 

 

C

 

E

 

 

 

X

 

 

 

 

 

-

 

 

 

 

 

d

 

F

 

 

 

 

 

 

t

 

D

 

 

 

 

 

 

 

i

 

 

 

 

 

 

 

 

r

P

 

 

 

 

 

NOW!

o

 

 

 

 

 

 

 

 

 

 

 

BUY

 

 

 

 

 

to

 

 

 

 

w Click

 

 

 

144m

 

 

 

 

w

 

 

 

 

 

 

 

 

 

w

 

 

 

 

 

 

 

o

 

.

 

 

 

 

 

.c

 

 

p

 

 

 

 

g

 

 

 

 

df

 

 

n

e

 

 

 

 

-xcha

 

 

 

 

 

 

 

hang

e

 

 

 

 

 

 

 

C

 

E

 

 

 

 

X

 

 

 

 

 

 

-

 

 

 

 

 

d

 

 

F

 

 

 

 

 

 

t

 

 

D

 

 

 

 

 

 

 

i

 

 

 

 

 

 

 

 

 

r

P

 

 

 

 

 

NOW!

o

 

 

 

 

 

 

 

 

 

 

 

 

BUY

 

 

 

 

 

 

to

 

 

 

 

 

Глава 6. Людям свойственно ошибатьсяClick

 

 

 

 

 

m

 

 

 

 

 

 

w

 

 

 

 

 

 

 

o

 

 

w

 

 

 

 

 

 

 

 

w

 

 

 

 

 

 

.c

 

 

.

 

 

 

 

 

 

 

 

p

 

 

 

 

g

 

 

 

 

 

df

 

 

n

e

 

 

 

 

 

-x cha

 

 

 

 

звавший уровень исходя из того, насколько легко возобновить рабо% ту или найти обходной путь.

Как исправить ошибку

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

От их полноты зависит стратегия обработки каждой ошибки. Пропу% щенный обработчик возможного сбоя приводит к появлению про% граммного дефекта, который редко проявляется и с трудом локализу% ется, так что тщательно обдумывайте все сбойные ситуации.

Когда обрабатывать ошибки

Когда следует обрабатывать каждую ошибку? Не всегда это следует де% лать сразу при ее обнаружении. Есть две точки зрения.

Как можно скорее

Обрабатывайте каждую ошибку, как только обнаружите ее. Пока причина ошибки не устарела, сохраняется важная контекстная ин% формация, и код обработки оказывается яснее. Это знакомая нам технология самодокументирования кода. Обработка ошибок вбли% зи их источника означает, что меньше кода будет выполнено при некорректном состоянии программы.

Обычно это лучший подход в том случае, когда функции возвраща% ют код ошибки.

Как можно позднее

Напротив, можно попытаться всеми силами оттягивать обработку ошибок. При этом учитывается, что код, обнаруживший ошибку, часто не знает, как с ней поступить. Многое зависит от контекста. Когда не найден некий файл, то можно сообщить об этом пользова% телю, если это файл с загружаемым документом. Если же это файл индивидуальных настроек программы, то можно тихо проскочить дальше.

В таком случае лучше всего подходят исключительные ситуации; можно передавать исключение с одного уровня на другой, пока не определится, как поступить с ошибкой. Такое разделение обнаруже% ния и обработки может быть более понятным, но приведет к услож% нению кода. Вовсе не очевидно, что обработка ошибки умышленно откладывается на другое время, и, когда вы наконец займетесь ее обработкой, будет непонятно, где возникла ошибка.

Теоретически рекомендуется отделять «бизнес%логику» приложе% ния от обработки ошибок. Но часто это невозможно, поскольку на% ведение порядка неотделимо связано с этой бизнес%логикой, и раз% деление их кодирования может вызвать дополнительные трудно%

 

 

 

 

hang

e

 

 

 

 

 

 

 

C

 

E

 

 

 

 

X

 

 

 

 

 

 

-

 

 

 

 

 

d

 

 

F

 

 

 

 

 

 

t

 

 

D

 

 

 

 

 

 

 

i

 

 

 

 

 

 

 

 

 

r

 

P

 

 

 

 

 

NOW!

o

 

 

 

 

 

 

 

 

 

 

 

 

 

BUY

 

 

 

 

 

 

to

 

 

 

 

 

w Click

 

 

 

Обработкаm

ошибок

 

 

 

 

w

 

 

 

 

 

 

 

 

 

 

w

 

 

 

 

 

 

 

o

 

 

.

 

 

 

 

 

.c

 

 

 

p

 

 

 

 

g

 

 

 

 

 

df

 

 

n

e

 

 

 

 

 

-xcha

 

 

 

 

 

 

 

 

hang

e

 

 

 

 

 

 

 

C

 

E

 

 

 

 

X

 

 

 

 

 

 

-

 

 

 

 

 

d

 

 

F

 

 

 

 

 

 

t

 

 

D

 

 

 

 

 

 

 

i

 

 

 

 

 

 

 

 

 

r

P

 

 

 

 

 

NOW!

o

 

 

 

 

 

 

 

 

 

 

 

 

BUY

 

 

 

 

 

 

to

 

 

 

 

 

145Click

 

 

 

 

 

m

 

 

 

 

 

 

w

 

 

 

 

 

 

 

o

 

 

w

 

 

 

 

 

 

 

 

w

 

 

 

 

 

 

.c

 

 

.

 

 

 

 

 

 

 

 

p

 

 

 

 

g

 

 

 

 

 

df

 

 

n

e

 

 

 

 

 

-x cha

 

 

 

 

сти. Тем не менее централизованная обработка ошибок имеет свои преимущества: вы знаете, где находится этот код, и можете реали% зовать всю политику аварийного завершения/продолжения работы в одном месте, не рассеивая ее по множеству функций.

Томас Джефферсон однажды заявил: «Лучше отложить, чем ошибить% ся». Его слова не лишены смысла; наличие процедуры обработки оши% бок гораздо важнее, чем обработка отдельной ошибки. Тем не менее же% лательно стремиться к компромиссу, позволяющему уйти не настолько далеко, чтобы потерять смысл и контекст обрабатываемых ошибок, и не остаться столь близко, что обычный код оказывается загроможден% ным обходными маршрутами и тупиковыми путями обработки ошибок.

Обрабатывайте все ошибки в наиболее благоприятном контексте, когда становится ясно, как корректно с ней справиться.

Варианты реагирования

Допустим, вы перехватили ошибку. Вы готовы ее обработать. Что вы станете делать? Вероятно, то, что необходимо для корректной работы программы. Невозможно перечислить все существующие стратегии восстановления, но приведем наиболее распространенные типы ответ% ных действий:

Регистрация в журнале

Во всяком достаточно большом проекте должны быть средства веде% ния журналов. В них заносится важная информация по ходу рабо% ты, и они служат начальной точкой расследования при возникнове% нии проблем.

Журнал нужен, чтобы регистрировать интересные события в про% цессе разработки программы, иметь возможность глубже проник% нуть во внутренние механизмы ее функционирования и восстано% вить ход ее выполнения. Поэтому все возникающие ошибки должны быть подробно описаны в журнале программы; это одни из самых интересных и информативных событий. Старайтесь регистрировать все относящиеся к делу данные, основываясь на приведенном выше списке.

Для действительно темных ошибок, предвещающих катастрофиче% ские последствия, бывает разумно заставить программу «позвонить домой» – переслать разработчикам снимок самой себя или копию журнала регистрации ошибок, чтобы они могли предпринять дей% ствия.

Как вы будете потом работать с журналом – уже другая задача.

Создание отчета

Программа должна сообщать пользователю об ошибке, только когда не остается ничего иного. Не нужно бесконечно бомбардировать поль%

 

 

 

 

hang

e

 

 

 

 

 

 

C

 

E

 

 

 

X

 

 

 

 

 

-

 

 

 

 

 

d

 

F

 

 

 

 

 

 

t

 

D

 

 

 

 

 

 

 

i

 

 

 

 

 

 

 

 

r

P

 

 

 

 

 

NOW!

o

 

 

 

 

 

 

 

 

 

 

 

BUY

 

 

 

 

 

to

 

 

 

 

w Click

 

 

 

146m

 

 

 

 

w

 

 

 

 

 

 

 

 

 

w

 

 

 

 

 

 

 

o

 

.

 

 

 

 

 

.c

 

 

p

 

 

 

 

g

 

 

 

 

df

 

 

n

e

 

 

 

 

-xcha

 

 

 

 

 

 

 

hang

e

 

 

 

 

 

 

 

C

 

E

 

 

 

 

X

 

 

 

 

 

 

-

 

 

 

 

 

d

 

 

F

 

 

 

 

 

 

t

 

 

D

 

 

 

 

 

 

 

i

 

 

 

 

 

 

 

 

 

r

P

 

 

 

 

 

NOW!

o

 

 

 

 

 

 

 

 

 

 

 

 

BUY

 

 

 

 

 

 

to

 

 

 

 

 

Глава 6. Людям свойственно ошибатьсяClick

 

 

 

 

 

m

 

 

 

 

 

 

w

 

 

 

 

 

 

 

o

 

 

w

 

 

 

 

 

 

 

 

w

 

 

 

 

 

 

.c

 

 

.

 

 

 

 

 

 

 

 

p

 

 

 

 

g

 

 

 

 

 

df

 

 

n

e

 

 

 

 

 

-x cha

 

 

 

 

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

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

Конечно, такого рода сообщения возможны, если программа распо% лагает средствами интерактивности. Программам, действующим независимо от пользователя, приходится справляться с трудностя% ми самостоятельно; представьте себе стиральную машину, выводя% щую диалоговые окна!

Восстановление

Иногда единственным выходом оказывается немедленное прекра% щение работы. Но не всегда при возникновении ошибки программа обречена. Допустим, ваша программа сохраняет файл, а диск ока% зывается переполненным, и операция не может быть выполнена. Пользователь вправе рассчитывать, что программа сможет продол% жить работу, и вы должны это обеспечить.

Если код сталкивается с ошибкой и не знает, что с ней делать, пере% дайте ее выше. Скорее всего, у вызвавшего уровня найдутся средст% ва для восстановления.

Игнорирование

Этот вариант я включил лишь для полноты. Надо полагать, что к это% му моменту вы уже с негодованием отнесетесь ко всякому предложе% нию игнорировать ошибки. Если же вы решите не забивать себе го% лову обработкой ошибок и, перекрестившись, двинетесь вперед – удачи вам. Это причина большинства дефектов во всех программ% ных пакетах. Игнорирование сбоя, который может сорвать нормаль% ную работу системы, неизбежно приводит к долгим часам отладки.

Можно, однако, написать код, который позволяет ничего не делать при появлении ошибки. Противоречие? Нет. Можно написать код, который справляется с ситуациями нашего непоследовательного ми% ра, который корректно продолжает работу при наличии ошибки – но при этом код часто оказывается весьма сложным. Приняв такой подход, вы должны ясно сообщить об этом в коде, иначе его могут принять за неграмотно и некорректно написанный.

Игнорирование ошибок не экономит вашего времени. Вы потратите больше времени на выяснение причин некорректного поведения программы, чем вам понадобилось бы для написания обработчика ошибок.