The short answer is: No, not only do you not need to have an error handler in each procedure, but in fact you would usually not want an error handler in each procedure.
You will want to do the error handling where it makes most sense to do it. Often, you would only want an error handler in the highest-level procedure, i.e. the one that calls all the others; lower-level procedures should kick the problem upstairs and let errors "bubble up" to the higher-level procedure. Sometimes you will want some error handling in lower-level procedures.
For more, I refer you to these two excellent answers by @jtolle:
Also, an internet search will reveal that there is a whole literature on the web about error handling. Some of it is quite wrong, in my opinion! But if it sticks to what I wrote in the first two paragraphs, then it's worth considering.
Exit Sub
and End Sub
are fairly intuitive: the former stops execution of the current Sub and returns control to the procedure that called it (or stops execution entirely if the procedure was not called by another procedure). The latter is just a indication to the compiler that this where the code for this particular Sub ends -- and if executed, End Sub
behaves like Exit Sub
.
Resume
specifies what should happen next, after an error-handling routine is finished. Plain Resume
returns to the same statement that caused the error and tries to execute it again. Resume Next
skips the statement that caused the error, and instead goes to the statement immediately following it. Resume mylabel
goes to label mylabel:
.
If a label such as your ProcError:
is encoutered in the course of execution, then nothing special happens, and execution moves on to the next statement after the label. Of course in your example, ProcError:
will never get executed directly (i.e. not unless an error is raised) because there's an Exit Sub
just before it.
By the way, the ProcExit:
block should probably start with an On Error Resume Next
(i.e. keep on closing everything and exiting regardless of any errors) or alternatively, as pointed out by @Phydaux, an On Error Goto 0
(on error, stop execution), otherwise if something in there triggers an error, you may get into an infinite ping-pong loop between the error handler and the ProcExit:
code.
ProcExit:
On Error Resume Next ' or, alternatively, On Error Goto 0
Connection.Close
Connection = Nothing
Close File
SomePreciousResource.Release
Exit Sub
On Error Resume Next
after the Error Handler Label. Made me rethink what I'm doing. But, what if I want the line after the error ocurred get executed? Is it fine to useResume Next
in that case? Hope you get what I'm trying to say (english is not my mother language). – Oscilloscope