I have a large function/sub that does a ton of validations and error checking early on before going into an ETL design pattern. So I am using "C/C++"-esque error checking where you want to "fail early", i.e. if the validations fail, I call Return
(same as Exit Sub
) asap and no further code is executed.
Notice the repeating code in the VB.net code below:
If fn Is Nothing Then
lblDataError.Text = "<b>Error!</b> Could not upload your file. <b>Reason:</b> Filename is blank, please press the <kbd>Browse</kbd> button first to select the file, then press <kbd>Upload</kbd>."
divFail.Visible = True
Return
ElseIf Path.GetExtension(fn).ToLower() <> ".csv" Then
lblDataError.Text = "<b>Error!</b> Could not upload your file. <b>Reason:</b> Filename extension must be <kbd>.csv</kbd>."
divFail.Visible = True
Return
Else
For Each badChar As Char In System.IO.Path.GetInvalidFileNameChars
If InStr(fn, badChar) > 0 Then
lblDataError.Text = "<b>Error!</b> Could not upload your file. <b>Reason:</b> Filename contains invalid character(s)."
divFail.Visible = True
Return
End If
Next
End If
Is it possible to make a helper function such that it causes the calling function to return? If this isn’t possible in .NET, do any languages support this?
Public Function Fail(customErrorMessage as String)
lblDataError.Text = "<b>Error!</b> " & customErrorMessage
divFail.Visible = True
Return Return 'This line should cause the calling function to return.
End Function
Or should I just use a Boolean and do an if-statement after all the validations because this isn’t possible?
3
Answers
I suggest you look at using try/catch and exceptions. Supported in C# and pretty much any other language I can think of.
Building on Steve’s idea… to call your fail function inside each of your validations. You know you’re going to return, so something like this:
No, it’s not possible to exit a calling method from within a called method in VB. However, if you rethink your problem, there are usually alternate ways to structure your logic to avoid the duplication. For instance, in this case, one option would be to simply have an error message variable, and then do the displaying/returning once, at the end, if the variable is set:
In situations like this, it’s also often helpful to consider making a list of delegates to functions, and then you can loop through all the delegates, invoke each one and process the result in one place, the same way for all the delegates. Or, for more involved things, you could make each rule into a separate class, store a list of them, and check each one in a loop, similar to the delegates approach. In the code you provided, though, anything like that is probably overkill.
On a side note, the invalid file name characters check could be simplified to: