I believe the following works best, called the central error handling approach.
Benefits
You have 2 application launch modes: debugging and production. In debug mode, the code will stop if there is any unexpected error and will allow you to easily debug by going to the line where it happened by pressing the F8 key twice. In production mode, a meaningful error message will be displayed to the user.
You can throw out deliberate errors like this, which will stop the code from executing a message to the user:
Err.Raise vbObjectError, gsNO_DEBUG, "Some meaningful error message to the user" Err.Raise vbObjectError, gsUSER_MESSAGE, "Some meaningful non-error message to the user" 'Or to exit in the middle of a call stack without a message: Err.Raise vbObjectError, gsSILENT
Implementation
You need to “wrap” all routines and functions with any significant amount of code with the following headers and ehCallTypeEntryPoint headers, making sure that you specify ehCallTypeEntryPoint at all your entry points. Also pay attention to the msModule constant, which must be placed in all modules.
Option Explicit Const msModule As String = "<Your Module Name>" ' This is an entry point Public Sub AnEntryPoint() Const sSOURCE As String = "AnEntryPoint" On Error GoTo ErrorHandler 'Your code ErrorExit: Exit Sub ErrorHandler: If CentralErrorHandler(Err, ThisWorkbook, msModule, sSOURCE, ehCallTypeEntryPoint) Then Stop Resume Else Resume ErrorExit End If End Sub ' This is any other subroutine or function that isn't an entry point Sub AnyOtherSub() Const sSOURCE As String = "AnyOtherSub" On Error GoTo ErrorHandler 'Your code ErrorExit: Exit Sub ErrorHandler: If CentralErrorHandler(Err, ThisWorkbook, msModule, sSOURCE) Then Stop Resume Else Resume ErrorExit End If End Sub
The contents of the central error handler module:
''''''''''''''''''''''''''''''''''''''''''''''''''''''''''' ' Comments: Error handler code. ' ' Run SetDebugMode True to use debug mode (Dev mode) ' It will be False by default (Production mode) ' ' Author: Igor Popov ' Date: 13 Feb 2014 ' Licence: MIT ' '''''''''''''''''''''''''''''''''''''''''''''''''''''''''' Option Explicit Option Private Module Private Const msModule As String = "MErrorHandler" Public Const gsAPP_NAME As String = "<You Application Name>" Public Const gsSILENT As String = "UserCancel" 'A silent error is when the user aborts an action, no message should be displayed Public Const gsNO_DEBUG As String = "NoDebug" 'This type of error will display a specific message to the user in situation of an expected (provided-for) error. Public Const gsUSER_MESSAGE As String = "UserMessage" 'Use this type of error to display an information message to the user Private Const msDEBUG_MODE_COMPANY = "<Your Company>" Private Const msDEBUG_MODE_SECTION = "<Your Team>" Private Const msDEBUG_MODE_VALUE = "DEBUG_MODE" Public Enum ECallType ehCallTypeRegular = 0 ehCallTypeEntryPoint End Enum Public Function DebugMode() As Boolean DebugMode = CBool(GetSetting(msDEBUG_MODE_COMPANY, msDEBUG_MODE_SECTION, msDEBUG_MODE_VALUE, 0)) End Function Public Sub SetDebugMode(Optional bMode As Boolean = True) SaveSetting msDEBUG_MODE_COMPANY, msDEBUG_MODE_SECTION, msDEBUG_MODE_VALUE, IIf(bMode, 1, 0) End Sub ''''''''''''''''''''''''''''''''''''''''''''''''''''''''''' ' Comments: The central error handler for all functions ' Displays errors to the user at the entry point level, or, if we're below the entry point, rethrows it upwards until the entry point is reached ' ' Returns True to stop and debug unexpected errors in debug mode. ' ' The function can be enhanced to log errors. ' ' Date Developer TDID Comment ''''''''''''''''''''''''''''''''''''''''''''''''''''''''''' ' 13 Feb 2014 Igor Popov Created Public Function CentralErrorHandler(ErrObj As ErrObject, Wbk As Workbook, ByVal sModule As String, ByVal sSOURCE As String, _ Optional enCallType As ECallType = ehCallTypeRegular, Optional ByVal bRethrowError As Boolean = True) As Boolean Static ssModule As String, ssSource As String If Len(ssModule) = 0 And Len(ssSource) = 0 Then 'Remember the module and the source of the first call to CentralErrorHandler ssModule = sModule ssSource = sSOURCE End If CentralErrorHandler = DebugMode And ErrObj.Source <> gsNO_DEBUG And ErrObj.Source <> gsUSER_MESSAGE And ErrObj.Source <> gsSILENT If CentralErrorHandler Then 'If it an unexpected error and we're going to stop in the debug mode, just write the error message to the immediate window for debugging Debug.Print "#Err: " & Err.Description ElseIf enCallType = ehCallTypeEntryPoint Then 'If we have reached the entry point and it not a silent error, display the message to the user in an error box If ErrObj.Source <> gsSILENT Then Dim sMsg As String: sMsg = ErrObj.Description If ErrObj.Source <> gsNO_DEBUG And ErrObj.Source <> gsUSER_MESSAGE Then sMsg = "Unexpected VBA error in workbook '" & Wbk.Name & "', module '" & ssModule & "', call '" & ssSource & "':" & vbCrLf & vbCrLf & sMsg MsgBox sMsg, vbOKOnly + IIf(ErrObj.Source = gsUSER_MESSAGE, vbInformation, vbCritical), gsAPP_NAME End If ElseIf bRethrowError Then 'Rethrow the error to the next level up if bRethrowError is True (by Default). 'Otherwise, do nothing as the calling function must be having special logic for handling errors. Err.Raise ErrObj.Number, ErrObj.Source, ErrObj.Description End If End Function
To set yourself in debug mode, do the following in the Immediate window:
SetDebugMode True