Vb net on error resume next

The alternative to that simple error-handling combo is the Try...Catch, but it's not as simple as wrapping up your code with it.

Code Focused

Life Without On Error Resume Next

The alternative to that simple error-handling combo is the Try…Catch, but it’s not as simple as wrapping up your code with it.

Long before .NET arrived on the scene, the On Error statement in Visual Basic formed the foundation of that language’s error management options. Through the judicious use of On Error GoTo statements and related error objects, you could craft error-handling code that was every bit as rugged and nearly as structured as the modern Try…Catch alternative. But when you didn’t care anymore, there was this:

On Error Resume Next
DoSomethingUnsafe()
HereIsMoreDanger()

The On Error statement’s Resume Next clause told the world, «Do what you want; ask me later if I care.» It was a great way to ignore low-risk errors in your source code. But when misused, the statement could greatly complicate debugging and data issues. And, yet, there were times when it was the right tool. The cleanup of low-priority resources just before exiting an application is an example that comes to mind:

On Error Resume Next
resourceOne.Cleanup()
resourceTwo.Cleanup()
resourceThree.Cleanup()
End

When migrating such code to its structured alternative, the temptation is to wrap it all up in one large Try statement:

Try
  resourceOne.Cleanup()
  resourceTwo.Cleanup()
  resourceThree.Cleanup()
Catch
  ' ----- Ignore any error.
End Try
End

Unfortunately, this isn’t the correct conversion, because any exception thrown by the cleanup of resourceOne will cause the code to completely skip the two remaining logic lines. A more accurate translation into modern .NET code would provide error handlers for each trouble-prone statement, as shown in Listing 1.

Listing 1: The Correct Way To Use Try…Catch

Try
  resourceOne.Cleanup()
Catch
  ' ----- Ignore any error.
End Try
Try
  resourceTwo.Cleanup()
Catch
  ' ----- Ignore any error.
End Try
Try
  resourceThree.Cleanup()
Catch
  ' ----- Ignore any error.
End Try
End

The code in Listing 1 is correct, and it provides task-specific opportunities to deal with any errors that do occur, even when moving from a procedure that formerly tossed caution to the wind.

Despite the validity of this code, you might wonder how the Visual Basic .NET compiler deals with On Error Resume Next. By building your Visual Basic project, and then extracting out the compiled result using the .NET Framework Intermediate Language (IL) Disassembler tool (ILDASM.EXE), you can see exactly what the compiler does. It’s IL, so it’s not pretty. But the Visual Basic code presented in Listing 2 shows generally what the compiler attempts to do.

Listing 2: What the Compiler Tries To Do, in Visual Basic

Dim position As Integer
Try
  position = 1
Statement01:
  position = 2
  resourceOne.Cleanup()
Statement02:
  position = 3
  resourceTwo.Cleanup()
Statement03:
  position = 4
  resourceThree.Cleanup()
Statement04:
  position = 0
  GoTo EndOfLogic

DealWithIt:
  Select Case position
    Case 0: GoTo EndOfLogic
    Case 1: GoTo Statement01
    Case 2: GoTo Statement02
    Case 3: GoTo Statement03
    Case 4: GoTo Statement04
  End Select
Catch
  GoTo DealWithIt
End Try
EndOfLogic:
End

The code depends heavily on the GoTo statement, using it to jump back into the action if an error ever does occur halfway through. It seems like a dramatic increase in code.

I’m not an expert in software benchmarking, but my guess is that the performance overhead inherent in repeatedly entering and exiting error handling blocks exceeds the extra time consumed by assigning the position variable over and over again. And if no exception is ever thrown, the entire DealWithIt block is passed over completely.

Which method should you use when replacing your unstructured error statements? It’s difficult to answer without knowing the exact nature of your routine’s logic. But if you have a secret desire to read through pages of assembly language-style code, using the output from the Visual Basic compiler isn’t a bad place to start.

About the Author


Tim Patrick has spent more than thirty years as a software architect and developer. His two most recent books on .NET development — Start-to-Finish Visual C# 2015, and Start-to-Finish Visual Basic 2015 — are available from http://owanipress.com. He blogs regularly at http://wellreadman.com.

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

  • On Error GoTo строка — Активизирует подпрограмму обработки ошибок, начало которой определяется обязательным аргументом строка, значением которого может быть любая метка строки или номер строки. Если возвращается ошибка выполнения, управление передается на указанную строку и запускается обработчик ошибок. Аргумент строка должен определять строку в той же процедуре, в которой находится инструкция On Error; в противном случае возникает ошибка компиляции.
  • On Error Resume Next — Указывает, что возникновение ошибки выполнения приводит к передаче управления на инструкцию, непосредственно следующую за инструкцией, при выполнении которой возникла ошибка. Рекомендуется при доступе к объектам использовать эту форму инструкции, а не On Error GoTo.
  • On Error GoTo 0 — Отключает любой активизированный обработчик ошибок в текущей процедуре.

Замечания

Если не выполнена инструкция On Error, то любая ошибка выполнения является фатальной; это означает, что выводится сообщение об ошибке и выполнение программы прекращается.

«Включенным» обработчиком ошибок называют подпрограмму, которая указана в инструкции On Error; «активным» обработчиком ошибок является включенный обработчик ошибок, который обрабатывает текущую ошибку. Если ошибка возникает в самом обработчике ошибок (в промежутке между возникновением ошибки и выполнением инструкции Resume, Exit Sub, Exit Function или Exit Property), то обработчик ошибок, определенный в текущей процедуре, не может обработать ошибку. Управление в этом случае возвращается в вызывающую процедуру; если в вызывающей процедуре включен обработчик ошибок, то обработка ошибки передается ему. Если этот обработчик ошибок является в данный момент активным, т.е. уже обрабатывает ошибку, то управление снова передается назад в вызывающую процедуру и т.д. до тех пор, пока не будет найден включенный, но не активный обработчик ошибок. Если включенный, но неактивный обработчик ошибок найден не будет, ошибка становится фатальной в том месте программы, в котором она впервые возникла. При каждой передаче управления обработчиком ошибок в вызывающую процедуру эта процедура становится текущей. После завершения обработки ошибки обработчиком в любой процедуре возобновляется выполнение текущей процедуры с той ее части, которая указана в инструкции Resume.

Подпрограмма обработки ошибок не может быть процедурой Sub или Function. Эта подпрограмма должна быть частью программы, которая отмечается с помощью метки строки или номера строки.

Для определения причины ошибки в подпрограммах обработки ошибок используют значение свойства Number объекта Err. Необходимо обеспечить в подпрограммах обработки ошибок проверку или сохранение существенных значений свойств объекта Err перед тем, как может возникнуть новая ошибка или перед вызовом процедуры, в которой может возникнуть новая ошибка. Значения свойств объекта Err описывают последнюю ошибку. Текст сообщения об ошибке, соответствующего коду ошибки Err.Number содержится в свойстве Err.Description.

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

При обработке ошибок, возникающих при доступе к другим объектам, рекомендуется использовать конструкцию On Error Resume Next, а не конструкцию On Error GoTo. Проверка объекта Err после каждого взаимодействия с другим объектом позволяет устранить неопределенность в том, при доступе к какому объекту возникла ошибка. Это позволяет всегда точно знать, какой объект поместил значение кода ошибки в свойство Err.Number, а также в каком объекте возникла ошибка (эта информация содержится в свойстве Err.Source).

Конструкция On Error GoTo 0 отключает обработку ошибок в текущей процедуре. Эта конструкция не задает переход на строку 0 для обработки ошибок, даже если в процедуре имеется строка с номером 0. Если инструкция On Error GoTo 0 не выполнялась, то обработчик автоматически отключается при выходе из процедуры.

Для того, чтобы предотвратить выполнение программы обработки ошибок в тех случаях, когда ошибка не возникла, следует помещать соответствующую инструкцию Exit Sub, Exit Function или Exit Property сразу после подпрограммы обработки ошибки, как в следующем примере:

Sub InitializeMatrix(Var1, Var2, Var3, Var4)
	On Error GoTo ОбработкаОшибок
	. . .
	Exit Sub
ОбработкаОшибок:
	. . .
	Resume Next
End Sub

В этом примере программа обработки ошибок помещена между инструкциями Exit Sub и End Sub, что позволяет отделить ее от части программы, соответствующей нормальному выполнению процедуры. Программу обработки ошибок можно разместить в любом месте процедуры.

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

Err.Number = vbObjectError + 1052

Системные ошибки при вызовах библиотек динамической компоновки (DLL) не приводят к возникновению исключений и не перехватываются средствами Visual Basic. При вызове функций из библиотек DLL необходимо проверять, успешно ли возвращается каждое значение (согласно спецификациям API), и в случае неудачи проверять значение свойства LastDLLError объекта Err.

Пример

В начале этой программы инструкция On Error GoTo определяет положение подпрограммы обработки ошибок в процедуре. В данном примере попытка удалить открытый файл приводит к возникновению ошибки с кодом 55. Ошибка обрабатывается в подпрограмме, после чего управление возвращается инструкции, которая привела к возникновению ошибки. Инструкция On Error GoTo 0 отключает перехват ошибок. После этого инструкция On Error Resume Next задает отложенный перехват ошибок, что позволяет точно определить, в каком контексте возникла ошибка, генерируемая в следующей инструкции. Следует отметить, что после обработки ошибки вызывается метод Err.Clear для сброса значений свойств объекта Err.

Sub OnErrorStatementDemo()
	On Error GoTo ErrorHandler			' Включаем программу обработки 
						' ошибок.
	Open "TESTFILE" For Output As #1		' Открываем файл.
	Kill "TESTFILE"				' Попытка удалить открытый 
						' файл.
	On Error Goto 0				' Отключаем перехват ошибок.
	On Error Resume Next			' Откладываем перехват ошибок.
	ObjectRef = GetObject("MyWord.Basic")	' Запускаем несуществующий 
						' объект, а затем проверяем 
						' ошибку механизма управления 
						' программируемыми объектами.
	If Err.Number = 440 Or Err.Number = 432 Then
	' Выводим сообщение для пользователя и очищаем объект Err.
		Msg = "Ошибка при попытке открыть программируемый объект!"
		MsgBox Msg, , "Проверка отложенной ошибки"
		Err.Clear			' Очищаем поля объекта Err.
	End If	
Exit Sub					' Выходим из процедуры, чтобы
						' не попасть в обработчик.
ErrorHandler:					' Обработчик ошибок.
	Select Case Err.Number			' Определяем код ошибки.

Case 55						' "Ошибка "Файл уже открыт".
			Close #1		' Закрываем открытый файл.
		Case Else
	' Здесь размещаются инструкции для обработки других ошибок... 
	End Select
	Resume					' Возобновляем выполнение
						' со строки, вызвавшей ошибку.
End Sub


Recommended Answers

By using a Try…Catch statement you can catch the error and do something about it.
It’s a very useful debugging tool.

However, you don’t have to enclose every single piece of altering code in it’s own statement.
You can start the Try statement even before the line With Me and …

Jump to Post

ON ERROR RESUME NEXT is a holdover from the days before TRY-CATCH. It is still used in vbScript where the TRY-CATCH is not available. It was the only way to prevent your program from crashing on an error and typically resulted in endless error checking tests (ugly) such as

       

Jump to Post

All 6 Replies

Member Avatar


Oxiegen

88



Basically an Occasional Poster



Featured Poster


10 Years Ago

By using a Try…Catch statement you can catch the error and do something about it.
It’s a very useful debugging tool.

However, you don’t have to enclose every single piece of altering code in it’s own statement.
You can start the Try statement even before the line With Me and end it below the line End With, followed by the Catch statement with a messagebox displaying the error.

With On Error Resume Next, you won’t know if an error occured and on what line.
So you have no way of knowing and thus can’t do much about it.

Also.
Personally I feel that those types of error catching methods are depricated as they originate from the old-school VB type programming.
The Try…Catch statement is the .NET way.
That includes the use of MsgBox. Have you looked at MessageBox()?

Member Avatar


codeorder

197



Nearly a Posting Virtuoso


10 Years Ago

Thanks for the informative reply Oxiegen. :)

I basically need to run a Sub that will set values to TextBoxes with Ctype(someCoolForm.Controls("someCoolTextBox"),TextBox).Text="daniweb.com" and wanted to use the minimum amount of typing/lines to accomplish this, even if it throws an error in case a TextBox does not exist on a Form; since planning to use that Sub for multiple.Forms/.Apps.
.Using a Try/Catch, it will error on first error and go straight to the Catch part, which does Nothing for the remaining TextBoxes waiting in line for values, If they exist on a specified Form.

As for the On Error Resume Next, I think that it should stay as a .Net option, even if integrated from the previous non.Net Visual Basics. A very strong opinion from my point of view.

Regarding the «Have you looked at MessageBox()?»:
I have and it does offer a few/or one extra option(s) above the MsgBox, though for testing, MsgBox is less time typing and quicker results. :)

Member Avatar


Reverend Jim

4,202



Hi, I’m Jim, one of DaniWeb’s moderators.



Moderator



Featured Poster


10 Years Ago

ON ERROR RESUME NEXT is a holdover from the days before TRY-CATCH. It is still used in vbScript where the TRY-CATCH is not available. It was the only way to prevent your program from crashing on an error and typically resulted in endless error checking tests (ugly) such as

on error resume next
avg = total / numitems

If err.Number <> 0 Then
    'error processing code
    err.Clear   ' maybe
End If

Member Avatar


codeorder

197



Nearly a Posting Virtuoso


10 Years Ago

Reverend Jim, should I proceed with the On Error Resume Next or Not? Seems like the only clear.solution for this issue, other than a bunch of «GoTo» and tons of Try/Catches. AndAlso, thanx for code.sample, news2Me.

Member Avatar


Reverend Jim

4,202



Hi, I’m Jim, one of DaniWeb’s moderators.



Moderator



Featured Poster


10 Years Ago

I’ve done a ton of vbScript (most of my apps at work from 2000-2008 were glue, data mining and system maintenance apps) and I used ON ERROR RESUME NEXT a lot. Most of my apps ran unattended and it was not acceptable for them to abort. However, I would not recommend it for VB apps. This may be against the general concensus but my recommendation is to use code to test for possible errors prior to doing an operation where possible and use TRY-CATCH sparingly. For example, if you are planning to do a numeric operation on the contents of a textbox, my preference would be to do something like

If IsNumeric(txtMycontrol.text) Then
    'do regular stuff
Else
    'do error stuff
End If

With regular expressions and such it is fairly simple to validate textboxes to ensure the text is valid. For operations that are more difficult to pre-validate (database operations, for example) I would use a TRY-CATCH.

But that’s just my preference.

Member Avatar


codeorder

197



Nearly a Posting Virtuoso


10 Years Ago

I went ahead with the On Error Resume Next and it met the requirements needed for me to accomplish my «previous» task.

Thanx for any and all input from the both of you; quite more informative than expected. :)


Reply to this topic

Be a part of the DaniWeb community

We’re a friendly, industry-focused community of developers, IT pros, digital marketers,
and technology enthusiasts meeting, networking, learning, and sharing knowledge.

Понравилась статья? Поделить с друзьями:
  • Vaux com interface communication error or interface not powered from car
  • Vat2000 коды ошибок
  • Vast error обзор
  • Vast error на русском читать
  • Vast error комикс