Try-Catch exception handler VB.NET - vb.net

I'm working through a Hair Salon application in VB.NET. Basically the user is able to select the stylist, service(s), age category and enter the number of visits. I then have a Calculate button in order to calculate the total price. I'm required to use Try-Catch for exception handling but I'm not too familiar with it. I'm assuming it's used for error handling, in which case how would I check to see if client visits is greater than 0 and to check to see if the value entered is an integer? Here is what I've tried with the client visits:
Try
(intClientVists > 0)
Exit Try
Catch ex As Exception When
(intClientVists < 0)
Exit Try
End Try
Just hoping someone can steer me in the right direction because I'm not really sure what I'm doing for this particular aspect of the application. Thanks.

Yes, Try/Catch blocks are used for error handling. However, they're not really for this kind of error. Try/Catch blocks are more for errors made by the programmer or the computer (could not allocate memory, could not connect to database, could not open a file, tried to divide by zero, could not cast a value to the specified type) than for errors made by the user (entered a wrong number).
Instead, you want a simple If/Else block:
If intClientVists > 0 Then
'Do something
Else
'Do something else
End If
If you really want to use exception handling for this (again: not normally the best choice), here is how it might look:
Try
If intClientVists < 0 Then Throw New InvalidOperationException()
'Data is OK. Continue processing here
Catch Ex As InvalidOperationException When intClientVisits = 0
'Show one error message
Catch Ex As InvalidOperationException When intClientVisits < 0
'Show different error message
End Try

This MSDN article gives you a list of .NET exceptions that you can use in a Try-Catch. These are actual errors as opposed to input validation checking, like Joel explained.
Basically, you put some logic in the Try block, and if you want to do something in the case of a specific exception, then you catch that exception type and put your logic in that Catch block. Then as a "catch-all" just simply catch "Exception" to do something no matter what type the exception is.
In your particular case, it sounds like the most likely use of a Try-Catch would be if the user inputs the number of visits into a regular text box in which they could enter letters. Here is an example of what you could do for that:
Try
If CInt(txtNumVisits.Text) > 0 Then
'logic here
End If
Catch ex As Exception
'If user entered something other than an integer in that box then an InvalidCastException will be caught
'enter logic here for if that's the case. For example:
MessageBox.Show(Me, "Please enter a number >= 0", "Invalid Input")
txtNumVisits.Focus()
End Try

Related

VB not stopping at exceptions

I like VB.Net, but there is something that is driving me nuts. Too many times when an exception occurs, it simply continues somewhere else, usually by exiting the sub or function, but otherwise keeps on rolling. As an example, I was using Asc() instead of AscW(). It didn't throw an exception, it just left the function as if a Return was executed. Meanwhile I'm leaving red dot stop points all over like it has chicken pox trying to figure out what is causing it.
Is there a setting that can be used to used to actually cause VB to stop and give a line number?
Try catch statements will help you out greatly.
Take a read here: https://msdn.microsoft.com/en-us/library/fk6t46tz.aspx
Have you tried using a Try..Catch..Finally statement. E.g. The ex.string will put the exception into a string in the message and tell you the vb line.
Try
'code here
Catch ex as Exception
MessageBox.Show("Something went wrong. " & ex.ToString, "Data Error ")
End Try

Repeated error handling

So in my vb.net application, i've got alot of try and catch blocks for error handling, especially whenever my app talks to the db.
i'm running through a series of if/elseif statements to see if
ex.tostring.contains("Unable to connect to any of the specified MySQL hosts")
and various bits like that.
At the minute, I wrote this out and copy and pasted it into each catch, but I know there will be a much more efficient way to do this whereby the code is just in one place and called as and when required.
I tried to implement it as a function, but I had trouble passing info to the function.
So i thought I'd ask and see how you guys go about doing this?
You don't need multipe try...catch statements for a program. One is enough.
If i understood you correctly, you want to print or show the error that occured inside the Try block.
Public Sub main()
Try
'Do something
Catch ex As Exception
End Try
Try
'Do something else
Catch ex As Exception
End Try
If ex.tostring.contains("something") than
End Sub
Instead you can do something like this:
Public Sub main()
Try
'Do all your code here.
Catch ex As Exception
MsgBox(ex.ToString)
End Try
End Sub
In this part, the compiler will automaticlly print the error occured in the program.
You can perform some action based on the type of exception thrown. Checking the text if not recommended as this could change with a new version of .net or mysqldata
Try something like this:
Try
'
' Programming lines of code
'
Catch exError As MySqlException
' an error occurred with MySql
Catch e As Exception
' a General error occurred
Finally
' Cleanup custom and unmanaged resources if necessary
End Try
Have a look at the MySQL Documentation for their recommendations

How can it happened - if case statement throws exception "case else" start working?

It looks like impossible but...
Try
Select Case command
Case 1
smth()
Case 2
If Not validSmth() Then
Throw New Exception(errMsg)
Else
doSmth()
End If
Case 3
doSmthElse()
Case Else
Throw New Exception(errMsg2)
End Select
Catch ex As Exception
ProcessEx()
End Try
Firstly Case 2 runs. Throws exception. And right after this debugger shows that next processed statement is Case Else. Only after Case Else throws own exception Catch block start working. I've never seen this trick. Why can this happened?
I'm sure the block is entered once (not like this:first enter hit Case 2 and second hit Case Else).
Thanks for any ideas.
Update:
-To Matt Wilko. Thank you for answering. I've switch to Strict On in Options of VS2010 but nothing has changed. Command is variable, not function. Watch tool shows that on each step Command is the same ( Command = 2).
Answer
Fixed. Yeeaaaahhh. I simplefy code to
Try
Select Case 2
Case 2
Throw New Exception("123")
Case Else
Throw New Exception("345")
End Select
Catch ex As Exception
wtf(ex.Message)
End Try
and change project to Console app. This works as I mention. The fix was in Release mode. I was debugging in Release mode. When I switch to Debug mode everything goes as it should.
Thank everyone for rapid answers.
I've just tried a simple example of what you have shown, but for me it works as expected. When the exception is thrown, execution jumps right to the Catch and nowhere else. Output reads "EX:2".
I would set some more breakpoints to make sure you are not entering your code twice. If that fails, restart Visual Studio (sometimes the debugger just gets funky). I don't think its possible for the behavior you are describing to happen.
Sub Main()
Dim Command As Integer = 2
Try
Select Case Command
Case 1
Console.WriteLine("1")
Case 2
Throw New Exception("2")
Case 3
Console.WriteLine("3")
Case Else
Throw New Exception("ELSE")
End Select
Catch ex As Exception
Console.WriteLine("EX:" & ex.Message)
End Try
Console.ReadLine()
End Sub

How do I use Do Until with a previous Try Catch Exception to avoid running the code twice

i have this line of code to catch an exception if a letter is inputed, or if it is out of rang as a number, but I have added WHEN to avoid catching numberical data. Now how can I use an exception error to use it before my case statement in order to avoid running the code twice, cause once the case codes has been through it will run a clear txtbox which is already taken care by the try catch, don`t if thats clear for you but i understand it. here is the code in parts...
Try
'Integer Levels: intLvls is egual to the assigned text box, the first one from
'the top, this line of code allow the user input to be captured into a variable.
intLvls = txtBoxLvl.Text
Catch ex As Exception When IsNumeric(intLvls)
ErrTypeLetterFeild1()
Finally
analysingvalues1()
End Try
WHAT I WOULD LIKE TO DO: Use loop until refencing the exception error to avoid running this following part of the code:
Private Sub analysingvalues1()
Do Until IsNumeric (ex As Exception)<------how do i do this???
Loop
the case part of the code:
Select Case intLvls
'User is prompt with the following label: lblLvl "Level of salespersons 1 - 4"
'to make a choice from 1 to 4 as available values.
Case 1 To 4
'This line regulates the range of acceptable values, first textbox: must be egual
'or higher than 1 and lower or egual to 4. Upon such rules a validation becomes
'correct and is directed to the isValidCalculation sub.
isValidCalculation()
Case Is < 1
ErrType1NumberRangeFeild()
Case Is > 4
ErrType1NumberRangeFeild()
Case Else
If txtBoxLvl.Text = "" Then
ErrTypeClear1()
Else
If Not IsNumeric(txtBoxLvl.Text) Then
ErrType1NumberRangeFeild()
Else
ErrTypeLetterFeild1()
ErrTypeClear1()
End If
End If
End Select 'Ending choices.
End Sub
Tks for your help!
If you turn on Option Strict this:
intLvls = txtBoxLvl.Text
Will no longer compile. This should tell you that your doing something smelly.
Turn on Option Strict
The correct solution is not to blindly allow the runtime to cast string to int for you, and catch the exceptions.
When you are converting string user input to an integer, bad input is not an exceptional condition, it is something you should expect and code defensively for.
I would rewrite it to something like this:
'Integer Levels: intLvls is egual to the assigned text box, the first one from
'the top, this line of code allow the user input to be captured into a variable.
if integer.TryParse( txtBoxLvl.Text, intLvls )
analysingvalues1()
else
ErrTypeLetterFeild1()
Edit - As pointed out by Chris below, I meant Option Strict. I recommend using but Explicit and Strict, and Infer if available.

Is there a better way to get visual studio to ignore try/catch in debug mode

I want the designer to catch the error when I am debugging and I want the user to see my friendly message if an error occurs for them. I know I can acomplish this with the following:
#If Debug=False Then
Try
#End If
'some code here
#If Debug=False Then
Catch ex as exception
Messagebox.Show("Errors suck")
End Try
#End If
I do not want to have to write all the #statements and having them cluttering up my code. It seems like this should be a common need and there has to be a better way. Does anyone know a better way?
In VS.NET you can say whether you want the debugger to break when an exception is thrown (not just when it's unhandled).
Look on the Debug | Exceptions... menu item (Ctl-Alt-E on my keyboard shortcuts). Pick the excepption you're interested in, then tick the "thrown" box for that exception.
You can tick that box at several levels (all CLR exceptions, all CLR exceptions in a given namespace, or very specific exceptions)
There is no good way to get it to ignore a try catch other than what you've done. But you can make the code a little bit cleaner and essentially get the same effect. You essentially are trying to prevent the action in the catch block from running. A better way to do that is a conditionally compiled method.
Try
...
Catch ex As Exception
DebugLog(ex)
Throw
End Try
<Condition("DEBUG)> _
Public Sub DebugLog(ByVal ex As Exception)
Messagebox.Show("errors suck")
End Sub
In the catch section of your Try..Catch you should write the exception message, stacktrace, and anything else you may want to a log file -- additionally you could write that data to the Windows Event log as well.
At worst, you could just put break-points in the Catch section of your Try..Catch blocks, since you shouldn't normally hit them it should'nt be a big deal once setup.
Here is how I do it:
Enabled:
Try ' : Catch: End Try
doSomething
andSomeMore
etcEtc
' Try
Catch ex As Exception
handleException
End Try
Disable the above by deleting the two comment characters:
Try : Catch : End Try
doSomething
andSomeMore
etcEtc
Try
Catch ex As Exception
handleException
End Try