I am having a lot of troubles to catch an exception in a async DelegateCommand (Prism 5).
In constructor of the ViewModel:
cmdModificarPedido = New DelegateCommand(Of Object)(AddressOf OnModificarPedido, AddressOf CanModificarPedido)
In the ViewModel:
Private _cmdModificarPedido As DelegateCommand(Of Object)
Public Property cmdModificarPedido As DelegateCommand(Of Object)
Get
Return _cmdModificarPedido
End Get
Private Set(value As DelegateCommand(Of Object))
SetProperty(_cmdModificarPedido, value)
End Set
End Property
Private Function CanModificarPedido(arg As Object) As Boolean
Return True
End Function
Private Async Sub OnModificarPedido(arg As Object)
Try
Await Task.Run(Sub()
Throw New Exception("My Exception")
End Sub)
NotificationRequest.Raise(New Notification() With {
.Title = "OK",
.Content = "Command OK"
})
Catch ex As Exception
NotificationRequest.Raise(New Notification() With {
.Title = "Error",
.Content = ex.Message
})
End Try
End Sub
Why the Exception is not being catched? I know it is another thread, but it is supposed to be catched anyway by the external Try...Catch block (Try Catch outside of: await Task.Run(()).
Note: it is vb.net code, but a C# solution will be fine too.
UPDATE 2
Once I know there was a problem with my debugger configuration (first chance exceptions), I write a more realistic example with same problem:
Private Async Sub OnModificarPedido(arg As Object)
Try
Await Task.Run(Sub()
Try
throwMyException()
Catch ex As Exception
Throw New Exception(ex.Message)
End Try
End Sub)
NotificationRequest.Raise(New Notification() With {
.Title = "Pedido Modificado",
.Content = "Pedido " + pedido.numero.ToString + " modificado correctamente"
})
Catch ex As Exception
NotificationRequest.Raise(New Notification() With {
.Title = "Error",
.Content = ex.Message
})
End Try
End Sub
Public Async Sub throwMyException()
Throw New Exception("My Exception")
End Sub
And now it does not catch the exception when I press F5. It breaks in "throwMyException()", it does not catch the exception although it is called inside a Try Catch block.
Important: If I remove the Async word in "throwMyException", it does catch it!!!
What am I doing wrong now?
Thank you
There was no problem with the original code you posted - the debugger was just catching the exception before your code did, which is perfectly normal.
With the updated code, the problem is the use of Async Sub. Exceptions cannot be directly caught from Async Sub methods. You should use (non-Async) Sub or Async Func(of Task) instead. This principle is known as "avoid async void" in my MSDN article on async best practices.
Related
I have a webservice that implements a lazy handler that handles queries on db and fills list of structure. This is made to avoid to read from DB.
Basically I have:
Public Class Lazy_Handler
Implements IDisposable
Private lToRet As New List(Of External_Widget)
'[... other lists to be read from DB the first time]
Private Shared ReadOnly lazy As Lazy(Of Lazy_Handler) = _
New Lazy(Of Lazy_Handler)(Function() New Lazy_Handler())
Public Shared ReadOnly Property Instance As Lazy_Handler
Get
Return lazy.Value
End Get
End Property
Public Function list_of_external_widget() As List(Of External_Widget)
Try
If lToRet Is Nothing Then
lToRet = New List(Of External_Widget)
End If
If lToRet.Count > 0 Then
Return lToRet
End If
lToRet = New List(Of External_Widget)
'... QUERY FROM DB HERE, DETAILS OMITTED
Return lToRet
Catch ex As Exception
Purge("link_of_external_widget:" & ex.Message)
Return New List(Of External_Widget)
Finally
DBOperazioni.CloseConn()
End Try
End Function
End Class
so from my website I call something like
Dim list_of_external_widget As List(Of Lazy_Handler.External_Widget) = _
Lazy_Handler.Instance.list_of_external_widget()
I expect that the first time the lazy is created, then the query is executed. After that, no more lazy creations and no more queries on DB.
I'm right?
It works well, but sometimes (I don't know where) there something that becomes Nothing and I get error. What could it be?
Thank you
I have one doubt regarding Try-Catch block.
Below is my code
private void PopulateDDL()
{
try
{
if (my condition)
{
code
}
else
{
throw new Exception(ErrorMessage);
}
}
catch (Exception ex)
{
logerror(ex);
}
}
Which Catch block will be executed if error for below code
else
{
throw new Exception(ErrorMessage);
}
From MSDN:
When an exception is thrown, the common language runtime (CLR) looks
for the catch statement that handles this exception. If the currently
executing method does not contain such a catch block, the CLR looks at
the method that called the current method, and so on up the call
stack. If no catch block is found, then the CLR displays an unhandled
exception message to the user and stops execution of the program.
The catch block you have defined:
catch (Exception ex)
{
RaiseWebError(ex);
}
will be executed first for the exception throw new Exception(ErrorMessage);
If RaiseWebError re-throws the exception this will then be handled by the next try-catch block found futher up the call stack (i.e. the parent method you refer to). But if RaiseWebError handles the exception in some way (perhaps by logging the exception) execution will continue after the first try-catch.
I need to call a function when an Ajax page method function returns success and without button click as protected sub. I couldn't include the ClientScript directly in the method or in shared function and the Method doesn't allow calling Public Sub UpdateText() without Shared ... any ideas?
'''' Method for Ajax with SQL and other functions
'''' ----------------------------------------------------------
<WebMethod()> _
Public Shared Function SendOrder(ByVal fulldata As String,
_ByVal id As Integer) As String
Try
UpdateText()
Return "Success"
Catch ex As Exception
Return "failure"
End Try
End Function
And here is the function I need to call
'''' Function to call only on success
'''' ----------------------------------------------------------
Public Sub UpdateText()
Dim jsUpdate As String
Dim cstype As Type
Dim cs As ClientScriptManager = Page.ClientScript
Dim jsUpdateTxt As String = "<script language='javascript'>...</script>"
ClientScript.RegisterStartupScript(cstype, jsUpdate, jsUpdateTxt)
End Sub
Page method calls have to be static.They cannot interact with the instance properties and methods of your Page class, because a page method call creates no instance of the Page or any of its controls.
after return either Success or failure, you can coding ajax methods in the client side like that
PageMethods.SendOrder(fulldata,id,OnRequestComplete, OnError);
function OnRequestComplete(result) {
//ToDo
}
function OnError(result) {
//ToDo
}
We are developing a webservice for a client. We are not supose to throw SoapExceptions, so instead, we catch every exception server side, and return a custom Exception class.
Public Class Order
...
End Class
Public Class MyException
...
End Class
And then in my webservice a function (webmethod):
Public Function GetOrder(ByVal id As Integer) As Object
Try
...
Return New Order()
Catch ex As Exception
Return New MyException(ex.Message)
End Try
End Function
The problem now is, that since my webmethod is returning the type [Object]. The wdsl that is generated does not contain the order, or the exception.
I can change the [Object] to [Order] Or [MyException], but only one of them is generated in the wsdl.
So does anybody have an idea of how i should handle this? I want both the MyException type and the Order type in my wsdl, but i just cant get it working.
Thank you all.
If your definition of MyException
Public Class MyException
inherits System.Exception
...
End Class
then you shouldn't need to return the Custom Exception just throw it.
then you can define
Public Function GetOrder(ByVal id As Integer) As Order
Try
...
Return New Order()
Catch ex As Exception
Throw New MyException(ex.Message)
End Try
End Function
As I recall (and it's been a while) trying to return multiple objects from a web method can prove to be extremely troublesome
If you really want to return multiple objects, then maybe you should create a "wrapper" object, e.g something like this:
'please note: I don't normally use VB.NET, so there might be some errors
Public Class OrderResponse
Public Property Order() As Order
Get
Return m_Order
End Get
Set
m_Order = Value
End Set
End Property
Private m_Order As Order
Public Property Exception() As MyException
Get
Return m_Exception
End Get
Set
m_Exception = Value
End Set
End Property
Private m_Exception As MyException
End Class
Then change your method to return an instance of that class, with either the property Order or Exception set to the respective value:
Public Function GetOrder(ByVal id As Integer) As OrderResponse
...
End Function
I'm a little bit stuck with a asp.net project that i'm doing! I have got a class that is called from the code behind and many of its function have no return type ie, being void. How does one do exception handling then??? Also, if the function within the class does have a return type of, for instance, a dataset how would one then return an exception or indicate that an exception had occured? I have attached the following code from my class which is referenced from the code behind.
public void fnRecord(string []varList, string fnName)
{
try
{
String x;
StringBuilder SQLParameters = new StringBuilder();
SQLParameters.AppendLine("SELECT #{Function}(");
{
SQLParameters.Replace("#{Function}", fnName);
}
for (int i = 0; i < varList.Length; i++)
{
x = varList[i].ToString();
SQLParameters.Append("'" + x + "',");
}
SQLParameters.Remove((SQLParameters.Length - 1), 1);
SQLParameters.Append(")");
string SQLCMD = SQLParameters.ToString();
conn.Open();
NpgsqlCommand command = new NpgsqlCommand(SQLCMD, conn);
Object result = command.ExecuteScalar();
}
catch (NpgsqlException ne)
{
//return ne;
}
catch (Exception x)
{
//error code
}
finally
{
conn.Close();
}
}
Any help would be appreciated!
Thanks
Only catch the exceptions where you intend to handle them properly. If you want to reflect the errors in the UI, catch them at the UI. If you want to handle them and try to deal with the issue in the business logic, then catch them and handle them at that point.
By the way, your code is susceptable to SQL injection attacks. Best go learn something about parameterised queries.
You don't return exceptions. You throw them. That's the point of exceptions - you don't want exception handling cluttering your method signatures!
In your catch clauses, you don't actually do anything to handle the exceptions. Then you should not catch them at all, just let them bubble up to your code-behind, and catch them there - put a try-catch round the method call.
Alternatively, catch your SQL exceptions in your method, then throw a new exception with some sensible message, adding the SqlExceptions as the inner exception, like this
catch (NpgsqlException ne)
{
throw new Exception("Your explanatory message here", ne);
}
finally
{
...
}
Cool thanks for the answers... working with the obout library so have to try and work out their exception handling functions too.