OnError script task not constructing error messages - vb.net

I have a script task(onError event handler) which gets the system error messages and stores them in the errorMessages user variable. The below script never finishes and goes in loop. I am trying to implement this link for sending email failure notifications. Any thoughts where this is going wrong?
Dim messages As Collections.ArrayList
Try
messages = CType(Dts.Variables("errorMessages").Value, Collections.ArrayList)
Catch ex As Exception
messages = New Collections.ArrayList()
End Try
messages.Add(Dts.Variables("ErrorDescription").Value.ToString())
' MessageBox.Show("Arraylist constructed")
Dts.Variables("errorMessages").Value = messages
'Dts.TaskResult = Dts.Results.Success
Dts.TaskResult = ScriptResults.Success

Check the declaration type of the errorMessages variable. I mistakenly declared it as string but it had to be type object. Changing that resolved the issue. Just posting it here in case someone faces similar issue.

Related

Concept dead letter exchange not working in my environment

I try to use the dead letter exchange with annotations in my java code. Maybe is my assumption wrong how it should work. But in my method processMpcMessage I deserialize the message from a Queue into a POJO. If I get a IllegalargumentException I want that the message is put onto a dead letter queue. I configured the deadletter exchange and routing key see my code example.
If I throw "throw new AmqpRejectAndDontRequeueException(msg, exception);" I expect that the message I consumed earlier is put onto the dead letter queue.
I get how ever the following debug message:
2019-02-07 13:35:42,009 [SimpleAsyncTaskExecutor-1] DEBUG {} - org.springframework.amqp.rabbit.listener.BlockingQueueConsumer - Rejecting messages (requeue=false)
Any advise is welcome
Regards
Dirk
#RabbitListener(bindings = #QueueBinding(
value = #Queue(
value = "${mpc.inbound.receive.queue}",
durable = "true",
arguments = {
#Argument(name = "x-dead-letter-exchange", value = "${mpc.inbound.dead.letter}"),
#Argument(name = "x-dead-letter-routing-key", value = "${mpc.inbound.receive.error.routing.key}"),
#Argument(name = "defaultRequeueRejected", value = "false")
}),
exchange = #Exchange(value = "${mpc.inbound.exchange}",
type = ExchangeTypes.TOPIC, durable = "true"),
key = "${mpc.inbound.routing.key}"
))
public void processMPCMessage(final Message message) {
//Here the message is deserialized in to a java object and this is where I want to throw a exception.
try{
}catch(IllegalArgumgenException ex){
throw new new AmqpRejectAndDontRequeueException(" a error message", ex);
}
}
Does the queue already exist?
Queues are idempotent; you can't change their properties (arguments) after they are created. Delete it first so it will be recreated.
If that's not it, turn on DEBUG logging to see what's going on.

How to dig into Exception data in VB.NET

I'm finding it hard to find the answer to my query in existing answers of Stackoverflow that's why I've decided to ask the question.
I want to handle the error with Try Catch but the default information from e.Message is not what I need.
Basically when using a breakpoint I can see that the Exception object has the data available when I dig in.
The PositionMessage type is string so I want to use this data to feed into Catch behavior. I just can't figure out how to assign the value from this specific field into a variable.
I hope you can help me with this.
The exception may be of type System.Management.Automation.RuntimeException in which case it implements IContainsErrorRecord. This means it has an ErrorRecord property (what you're looking for). You can try to cast it, and if it succeeds, you can access PositionMessage. Else (it's not a RuntimeException), then just treat it as a normal Exception.
Sub Main()
Try
' do stuff
Catch ex As Exception
Dim e = TryCast(ex, IContainsErrorRecord)
Dim message As String
If e IsNot Nothing Then
message = e.ErrorRecord.InvocationInfo.PositionM‌​essage
Else
message = ex.Message
End If
Console.WriteLine(message)
End Try
End Sub
NB: This is C#, but trivial to convert to VB. I do something like this:
results = pipeline.Invoke();
if (pipeline.Error.Count > 0)
{
var errors = pipeline.Error.Read() as Collection<ErrorRecord>;
if (errors != null)
{
foreach (ErrorRecord err in errors)
{
Console.WriteLine(err.InvocationMessage.PositionMessage);
}
}
}

UWP (VB.Net) StreamSocketListener not firing connected event

I'm trying to setup a socket listener in a Universal Windows Platform App. The app will run on a Raspberry PI and listen for communications from an in-motion scale.
I've setup a StreamSocketListener in my mainVM file. I've got commands to start and stop it. I've followed the few guides online i can find, but it won't fire the event when the scale sends the data. I've tested with a listener app that I downloaded, so i can confirm that the messages are being sent and my computer is able to receive them (no firewall issues). (I also know that only one app can listen to a port, so this tester is off when testing my program.)
I'll get one hit on the handler function when it first starts the connection, but i never get anything again. No errors, just nothing happening.
Commands:
Public Property cmdStart As New Command(Async Sub() Await StartListener(), True)
Public Property cmdStop As New Command(Sub() StopListener(), True)
Command Subroutines:
Private Async Function StopListener() As Task
If Connected Then
Await _prePriceListener.CancelIOAsync()
RemoveHandler _prePriceListener.ConnectionReceived, Nothing
_prePriceListener.Dispose()
Connected = False
End If
End Function
Private Async Function StartListener() As Task
If ValidateInput() Then
Try
_prePriceListener = New StreamSocketListener()
_prePriceListener.Control.KeepAlive = False
AddHandler _prePriceListener.ConnectionReceived, AddressOf HandlerReceived
Await _prePriceListener.BindServiceNameAsync("6021")
Connected = True
Catch ex As Exception
Message = ex.Message
End Try
End If
End Function
Event Handler:
Private Async Function HandlerReceived(sender As StreamSocketListener, args As StreamSocketListenerConnectionReceivedEventArgs) As Task
Dim msgReceived As String = ""
Dim inStream As Stream
Dim reader As StreamReader
Try
inStream = args.Socket.InputStream.AsStreamForRead()
reader = New StreamReader(inStream)
Catch ex As Exception
Return
End Try
Try
If reader IsNot Nothing Then
msgReceived = Await reader.ReadLineAsync()
HandlePrepriceRead(msgReceived)
End If
Catch ex As Exception
Return
End Try
End Function
I've tried with _prePriceListener.Control.KeepAlive set to both true and false. When true, it hangs on msgReceived = Await reader.ReadLineAsync() in the handler. I suspect that is the issue, but every fix i've found made no difference. My only other suspicion is incorrect use of Async/Await but i can't find much information to either confirm or deny that. (I think i know what i'm doing with that, but i may be at that level of knowing just enough to be dangerous...)
Anyway, any input would be greatly appreciated. Thanks.
Are you sure that the scale is sending an EOL (\n or \r or \r\n) HEX 13 and or 10 ? I could see your code waiting for an something the scale is never sending. *FYI I'm not sure what kind of scale you are using or how quickly it talks or your application but if the scale is on continuous feed this probably isn't going to work very well for you as the scale and all the parts along the way will buffer things and the weight will be gone by the time you process this event (after a while atleast)

Task.Run - Handling exceptions

I am having a function as below (kept only relevant code for this example):
Public Async Function RefreshCompanyCodesAsync() As Task(Of Boolean)
For ctr=1 to 2000
Await Task.Delay(1000).ConfigureAwait(False)
If ctr=5 Then Throw New ApplicationException("Why 5?")
Next
return true
End Function
As you can see, I am generating an exception when ctr = 5 just to check how the exception will be handled in the UI.
I then call this function inside a button click Async event:
Dim task1 = Task.Run(Sub()
RefreshCompanyCodesAsync()
End Sub)
Dim cTask = task1.ContinueWith(Sub(antecedent)
If task1.Status = TaskStatus.RanToCompletion Then
MsgBox("All done")
ElseIf task1.Status = TaskStatus.Faulted Then
MsgBox(task1.Exception.GetBaseException().Message)
End If
End Sub)
The task runs to completion instead of being faulted. I am guessing thats because a wrapper task runs to completion instead of the original task that threw an exception. However, am not sure how to get to the original task and handle the exception.
I have tried with Await.
Try
Await RefreshCompanyCodesAsync()
Catch ax As AggregateException
MsgBox(ax.Message)
Catch ex As Exception
MsgBox(ex.Message)
End Try
Exceptions get caught here, but the problem is I need to start multiple functionalities in parallel of which RefreshCompanyCodesAsync is only one of them. To do that, I believe launching those functionalities via Task.Run would be the best bet.
The actual functionality of the worker function in my case involves extensive DB and HttpClient activity and during this time, the UI responsiveness is driving me towards going in for Task.Run or Factory.StartNew
Also, have tried launching the task and Waiting for it so as to ensure evaluation of the result. However, my UI gets blocked when I do Task.Wait.
Any help is really appreciated.
Probably, what you want is
Dim task1 = RefreshCompanyCodesAsync()
That way there is no wrapper task. RefreshCompanyCodesAsync already is non-blocking which is important so that you don't freeze the UI.
You should avoid ContinueWith. Prefer await because it marshals you back to the UI thread.
I'll need to write this in C#:
var task1 = RefreshCompanyCodesAsync();
await Task.WhenAny(task1); //Wait without throwing.
MessageBox.Show(task1.Status.ToString());

Extract the user-defined Error message from exception

Inside my stored procedure, i just checked a particular condition and i'll throw Exception if that condition fails. like below,
Raise Exception '%', 'Hello world';
It is working fine, But the error message Hello world also comes with some other error code like stuffs like below in my front end,
DA00014:ERROR: P0001: Hello world
|___________________|
|
I really dont want this part to get displayed in the front end.
Is there any proper way available to filter out/Extract the right message from thrown exception.?
[Note: Please don't suggest me to do some string manipulations.]
DBMS : POSTGRESQL 9.0.3
Driver : Npgsql 1.0
Front End : VB.net
Npgsql Fastpath
If NpgsqlException.Errors is null in your exception handler then you have most likely hit a bug in Npgsql Fastpath (well I consider it a bug anyway). Here is the offending line in version 2 but the same issue exists in version 1.
It basically boils down to this code where a proper NpgsqlError is constructed and then thrown away when raising the exception by calling ToString() on it.
NpgsqlError e = new NpgsqlError(conn.BackendProtocolVersion, stream);
throw new NpgsqlException(e.ToString());
The fix would be as simple as changing the code to this and using the already supported ability of NpgsqlException to take in a list of NpgsqlError in the constructor.
NpgsqlError e = new NpgsqlError(conn.BackendProtocolVersion, stream);
throw new NpgsqlException(new ArrayList(e));
So in summary you can't do it without string manipulation unless you compile your own version of Npgsql patching the issue.
Npgsql
If you aren't using Fastpath then the thrown NpgsqlException object contains an Errors property which should be a non null list. This is an example of extracting the message from the first error.
(ex.Errors[0] as NpgsqlError).Message
try this..
Inside your store procedure place an extra character in message. e.g
Raise Exception '%', '|Hello world';
On Front end split your message on character "|", and display second index of array. e.g
Try
' your code..
Catch ex As Exception
Dim arr As String() = ex.Message.Split("|")
If arr.Count > 1 Then
MessageBox.Show(Convert.ToString(arr(1)))
Else
MessageBox.Show(Convert.ToString(ex.Message))
End If
End Try
If i understood, you can try this once
IF condition match -- (your condition)
BEGIN
RAISERROR('Hello world', 16,16)
return
END
and in expception
can use like
catch(exception ex)
{
// ex.Message
// ex.InnerException.Message
}
This should work:
Catch ex As Exception
lblMsg.Text = ex.Message.Replace("ERROR: P0001: ", "")
End Try