1

I'm lead to believe that the vba IDE doesn't allow proper breaking on errors. I asked a question on how to identify runtime errors here:

How do I break on errors?

The solution / workaround seems to be to use On Error GoTo ErrorHandler or similar. I'm trying to make that work but haven't had much success.

According to Microsoft On Error GoTo will send you to the specified code of region when a runtime error occurs (https://msdn.microsoft.com/en-us/library/5hsw66as.aspx). Based on my experience, that's not the whole story. This question is about how to actually make that solution work.

So I have the following function:

Function generateTimeseries() As Variant

On Error GoTo ErrorHandler

Dim currentArray As Range

currentArray = Selection.Range ' this doesn't work - I don't care why

generateTimeseries = currentArray.Rows

Return

ErrorHandler:
    Debug.Assert False
    Resume ' break here if you want to catch errors

End Function

This function never enters the ErrorHandler code. Instead, it falls over on Selection.Range, with the function simply returning #VALUE. I don't actually care why this breaks, I just want to know how I can get the IDE to tell me that it actually fell over on that line, without me jumping through the code manually.

Community
  • 1
  • 1
quant
  • 17,534
  • 24
  • 93
  • 186
  • "This function never enters the ErrorHandler code": Can't reproduce this. For me, it enters the ErrorHandler code. Two errors: 1. Since `currentArray` is an objekt, it must be set via `Set`: `Set currentArray = Selection`. 2. `Selection` may be a `Range` but if so, its `Range` method needs parameters. And what shall `Return` do in this context? – Axel Richter Apr 23 '16 at 06:25
  • @AxelRichter I found the problem. See my posted answer. – quant Apr 23 '16 at 06:37

2 Answers2

1

I just tested and your error handler works, it breaks correctly on

Debug.Assert False

--> check the debugger options.

However this is not a correct way to handle errors in vBA, because if you compile your application and forget to adapt such error handler, when a user will encounter an error in the procedure, the application will fall into an infinite loop.

In mostly all situations, you have to throw a msgbox to let the user know that an error has occurred, and terminate the current procedure. The only situation where this is not applicable is when you do something that can trigger an error but you know it and deliberately want to bypass the error. It's a rare situation.

I have never used Assert method and this is how I handle my errors in every procedure

Function generateTimeseries() As Variant

    On Error GoTo ErrorHandler

    Dim currentArray As Range

    currentArray = Selection.Range ' this doesn't work - I don't care why

    generateTimeseries = currentArray.Rows

Exit_Function:
       Exit Function

ErrorHandler:
        MsgBox Err.Description, vbCritical, "Error " & Err.Number
        Resume Exit_Function ' breakpoint here if you want examine the code after error, otherwhise it terminates the function
        Resume ' Once  the code breaks on the above line, move to this instruction and F8 to return to the statement in error

End Function
Thomas G
  • 9,222
  • 7
  • 24
  • 36
  • Thanks. That's much better than what I had. As for the reason it didn't break on errors. See my answer. I'll mark this as the answer. – quant Apr 23 '16 at 06:40
0

I had enabled the feature to "Break on all Errors" in an earlier attempt to break on all errors.

I turned this off by going to Tools->Options->General and replacing Break on All Errors with Break on Unhandled Errors.

It turns out that Break on All Errors is Windows for "Break on Some Errors, but just return garbage if it's a UDF error".

quant
  • 17,534
  • 24
  • 93
  • 186
  • No, it means break on all errors but unhandled errors in a UDF **called from a cell** simply result in a #VALUE error rather than throwing the user into the VBE. – Rory Apr 23 '16 at 08:04