# Visual Basic > Visual Basic .NET >  [RESOLVED] How can I get the ex.Message error from a Try-Catch Boolean Function?

## threeeye

Hi guys,
Quick question...
I have a Function that stops a Windows Service:


```
    Private Function Test(Service As String) As Boolean
        Try
            Dim sc As New ServiceController(Service)

            If sc.Status = ServiceControllerStatus.Running Then sc.Stop()
            sc.WaitForStatus(ServiceControllerStatus.Stopped)
            Return True
        Catch ex As Exception
            EventLog.WriteEntry(ex.Message)
            Return False
        End Try
    End Function
```

How can I get the ex.Message error from a Try-Catch Boolean Function if the Function returns False?

Thanks

----------


## OptionBase1

Maybe I'm misunderstanding, but you should be able to just change the return type to String.  Have an empty String returned when successful, and return ex.Message when there is an exception.

----------


## OptionBase1

Or you could do something like this:



```
Private Function Test(Service As String, ByRef ErrMsg As String) As Boolean
```

Then, in the Catch, you would just add this before your Return False:



```
ErrMsg = ex.Message
```

You would have to change your calling code to pass another String variable that will then contain any error message after the function is called.

----------


## threeeye

Thanks for the reply




> Maybe I'm misunderstanding, but you should be able to just change the return type to String.  Have an empty String returned when successful, and return ex.Message when there is an exception.


If I do this, I'll not get the False, I'd only get the ex.message...
(although, I can say that if I get a string, I know it's an error)




> Or you could do something like this:
> 
> 
> 
> ```
> Private Function Test(Service As String, ByRef ErrMsg As String) As Boolean
> ```
> 
> Then, in the Catch, you would just add this before your Return False:
> ...


I don't know how this would work...
Maybe if I return an array (the fist value is the boolean, the second the error (if there is no error, it'll be null))?

----------


## vbdotnut

Cant you just put the function call into a try block? Either your value will be returned or an exception from the call

----------


## threeeye

> Cant you just put the function call into a try block? Either your value will be returned or an exception from the call


So both the function call and code inside the function are in a Try block?
Or can I get away with only 1 try block (calling the function)?
Good idea, thanks

----------


## OptionBase1

> Originally Posted by OptionBase1
> 
> 
> Or you could do something like this:
> 
> 
> 
> ```
> Private Function Test(Service As String, ByRef ErrMsg As String) As Boolean
> ...


No, you are massively over (or possibly under) thinking this.  Spend a few minutes reading this:

https://learn.microsoft.com/en-us/do...d-by-reference

----------


## Shaggy Hiker

You are logging the error already. What more would you do with the string? The answer to that question would drive the best approach to solving this. Both the ByRef argument and returning a string are things that I have done when the situation warranted it. Another would depend on what your logging did. If it could raise an event, then you could get the string that way. Alternatively, it might make sense to add it to a class level List(of String). It all really depends on why you want that string.

----------


## threeeye

> You are logging the error already. What more would you do with the string? The answer to that question would drive the best approach to solving this. Both the ByRef argument and returning a string are things that I have done when the situation warranted it. Another would depend on what your logging did. If it could raise an event, then you could get the string that way. Alternatively, it might make sense to add it to a class level List(of String). It all really depends on why you want that string.


I have 3 codes that needs to run in order:
Function1 = stop the service
Function2 = copy new version of the service (self updating service - kinda)
Function3 = start the service

If Function1 = True, then continue to Function2, then Function3.
But if Function1 fails (it returns False), then run Function3 (skipping on 2) and save the error (ex.Message) somewhere and alert me (somehow - email?).
It is critical that Function2 runs AFTER Function1 ended successfully (because you can't overwrite a file while it's in use).

----------


## OptionBase1

> I have 3 codes that needs to run in order:
> Function1 = stop the service
> Function2 = copy new version of the service (self updating service - kinda)
> Function3 = start the service
> 
> If Function1 = True, then continue to Function2, then Function3.
> But if Function1 fails (it returns False), then run Function3 (skipping on 2) and save the error (ex.Message) somewhere and alert me (somehow - email?).
> It is critical that Function2 runs AFTER Function1 ended successfully (because you can't overwrite a file while it's in use).


The critical order of operations shouldn't be an issue unless you are using multiple threads.  If you are struggling with what to do with the error message, such as how do you have your program send an email, that should be asked in a new thread.

Otherwise, the answer to what this thread was about is as simple as the code below:



```
Private Sub DoTheNeedFull()

    Dim strErrMsg As String
    Dim blnServiceStoppedSuccessfully As Boolean

    blnServiceStoppedSuccessfully = Function1("Contoso Plinkenstein Service", strErrMsg)

    If blnServiceStoppedSuccessfully = True Then
        Function2()
    Else
        EmailMyselfTheErrorMessage(strErrMsg)
    End If

    Function3()

End Sub

Private Function Function1(Service As String, ByRef strErrMsg As String) As Boolean
    Try
        Dim sc As New ServiceController(Service)
        If sc.Status = ServiceControllerStatus.Running Then sc.Stop()
        sc.WaitForStatus(ServiceControllerStatus.Stopped)
        Return True
    Catch ex As Exception
        'EventLog.WriteEntry(ex.Message)
        strErrMsg = ex.Message  ' The value assigned to strErrMsg is retained when control is passed back out of this function
        Return False
     End Try

End Function
```

----------


## threeeye

> The critical order of operations shouldn't be an issue unless you are using multiple threads.  If you are struggling with what to do with the error message, such as how do you have your program send an email, that should be asked in a new thread.
> 
> Otherwise, the answer to what this thread was about is as simple as the code below:
> 
> 
> 
> ```
> Private Sub DoTheNeedFull()
> 
> ...


Thanks for the reply
I'll mark this thread as resolved, this is exactly what I meant, I just didn't know how to do it!

And as for this part:



> such as how do you have your program send an email, that should be asked in a new thread.


Sorry, this part I was just thinking out loud...
I know how to do that...

Thanks again

----------


## vbdotnut

I really dont think you have to do any of this. See if you get the same message youre passing around if you remove the try block from the function and just put the call in the try block


```
    Private Sub Button2_Click(sender As Object, e As EventArgs) Handles Button2.Click
        Try
            Dim GetFail As String = WillFail()
        Catch ex As Exception
            MsgBox(ex.Message)
        End Try
    End Sub
    Private Function WillFail() As String
        Return "Length is 12".Substring(0, "Length is 12".Length - 13)
    End Function
```

----------

