ПОНЯТНО О Visual Basic NET (том 3)

Обработка ошибок Исключения Оператор Try


Здесь нас интересуют только исключения, то есть ошибки выполнения (см. 1.3.8).

Суть проблемы. Многие функции, процедуры и вообще операторы, которыми вы пользуетесь в VB, вовсе не обязаны при любых обстоятельствах успешно завершать свою работу. Например, пусть вы запустили процедуру, в которой встречается оператор копирования файла 13.txt  из папки c:\temp в папку c:\temp\222:

Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click

        Dim a = 3

        File.Copy("c:\temp\13.txt", "c:\temp\222\13.txt")

        MsgBox("Ура! Файл скопирован!")

        Dim b = 8

End Sub

но забыли предварительно создать файл 13.txt в папке c:\temp. Метод File.Copy не может выполнить свою работу, VB выдает сообщение об ошибке и работа приложения прерывается. Говорят, что было выброшено исключение. Не в том смысле, что выброшено в мусорное ведро, а в том смысле, как выбрасывают лозунги, флаги, то есть выброшено из небытия в зону нашего внимания. Рядовой пользователь, работающий с вашим приложением, окажется в затруднительном положении. Он совсем не обязан разбираться в английском тексте сообщения, и если он даже догадается, в чем дело, и создаст нужный файл, все равно приложение надо будет запускать заново, так как оно прервано. Вы, как программист, должны учитывать, что с вашим приложением будут работать рядовые пользователи, причем даже не очень квалифицированные. Поэтому при программировании вы должны предугадать все возможные неправильные действия пользователя (за исключением выбрасывания компьютера в форточку), чтобы при таких действиях приложение, во-первых, не прерывалось, а во-вторых – выдавало вразумительное сообщение на русском языке и советы по выходу из затруднительной ситуации.

Кое-что в этом направлении мы уже делали в 7.7, предохраняя калькулятор от арифметических действий над текстом и от деления на ноль. Но там мы именно предохраняли проект от ошибок, не допускали их возникновения, не разрешали арифметических действий над текстом и деления на ноль. Здесь же мы будем рассматривать ситуации, когда о недопущении ошибки мы не смогли позаботиться, ошибка поэтому все же произошла и теперь нам нужно ее «обезвредить».


Таким образом, одна из целей достигнута – программа не прерывается. Поговорим о второй цели – о выдаче вразумительного сообщения с советами.

Вся обработка ошибки состоит в выполнении операторов, написанных нами между строками Catch и End Try. У меня обработка пока очень простая и не очень полезная. Сначала, как видите, выполняется оператор Beep(), чтобы привлечь внимание пользователя. Затем выдается сообщение об ошибке. Суть сообщения определяется свойством Message объекта ex. Если ошибка произошла из-за отсутствия файла 13.txt в папке c:\temp, то сообщение будет таким:





Рис. 19.2

Как видите, сообщение Message выводится на английском языке. Переводится оно так: «Не могла найти файл c:\temp\13.txt». Если вы знаете английский, то понимаете, в чем дело, нажимаете ОК, создаете файл, затем снова запускаете процедуру. Все в порядке.

Выводим собственные сообщения (по-русски). Ну а как насчет русского языка? Действительно, нас никто не заставляет выводить сообщение ex.Message. Давайте вместо

            MsgBox("При выполнении процедуры произошла следующая ошибка:   " & ex.Message)

напишем по-русски так:

            MsgBox("Ошибка: файл  c:\temp\13.txt  не существует. Создайте его и снова нажмите на кнопку.")

Вот это другое дело! Никакого английского и все понятно. И все бы хорошо, но тут нас ждет опасность. Дело в том, что при выполнении копирования файла причин у ошибки может быть несколько. Пусть, например, в папке 222 файл 13.txt уже есть, а вы снова запускаете процедуру копирования. Если вы заметили, наша File.Copy не допускает записи скопированного файла на место старого. Следовательно возникнет ошибка. Вот какое сообщение выдаст наш англоязычный MsgBox:



Рис. 19.3

что означает: «Файл  c:\temp\222\13.txt  уже существует». Новый же MsgBox обманет нас, на все случаи жизни заявляя, что он не может найти файл c:\temp\13.txt.

При моей простой обработке и не могло быть иначе. Чтобы справиться с ситуацией, усложним обработку ошибки. Вот что теперь мы поместим в процедуру между строками Catch и End Try:



Catch ex As Exception

    Beep()

    If Not File.Exists("c:\temp\13.txt") Then

        MsgBox("Ошибка: файл  c:\temp\13.txt  не существует. Создайте его и снова нажмите на кнопку.")

    ElseIf File.Exists("c:\temp\222\13.txt") Then

        MsgBox("Ошибка: файл  c:\temp\\222\13.txt  уже существует. Сотрите его и снова нажмите на кнопку.")

    Else

        MsgBox("Произошла непонятная ошибка при копировании")

    End If

End Try

Здесь мы использовали метод Exists класса File, который принимает значение True, если файл существует, и False – если нет. Поскольку кроме двух разобранных ошибок мыслимы и другие, неведомые для нас, я все же включил в оператор If  третью ветвь, в которой честно сознаюсь в своей некомпетентности.

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


Содержание раздела