Is it possible to catch a MailException when sending an e-mail?
I want to catch it in scenarios like mail server is down, malformed e-mail address, etc.
I see the MailException in the console but I cannot catch it when I call Mailer.send(). The Mailer.send() sends the e-mail asynchronously and thus I cannot catch the exception. How can I wait for the result suspending the HTTP request?
Another question: Does the Mailer.sendAndWait() suspend the request?
First the mail() method might throw a MailException if sending mail fails.
The send methods return a Future of type Boolean, if you call get() on the future you will get the result of the mail sending, mind that this call is blocking and will wait for the mail sending to finish.
This is the same thing as using sendAndWait()
This get can also throw an ExecutionException but I don't have the impression this is used by the play mailer. Instead you get back false from the future and the exception is logged.
SendAndWait() does not suspend the request as far as I can see in the sources
more info here:
http://download.oracle.com/javase/1,5.0/docs/api/java/util/concurrent/Future.html
https://github.com/playframework/play/blob/master/framework/src/play/mvc/Mailer.java
https://github.com/playframework/play/blob/master/framework/src/play/libs/Mail.java
Related
I'm new in mirth so sorry if my question may seems naive.
I've a mirth channel that recives hl7 messages, and this is fine, also I've some filters and transformers both in Source and Destination.
When all is fine at the end of destination I send an ACK with a message, for this for this purpose I've made this function in code Templates:
function getAck(success, detailMessage, statusMessage) {
if (!detailMessage)
detailMessage = success ? "Operation completed successfully" : "Some error occours";
if(!statusMessage)
statusMessage = detailMessage;
if (success) {
ack = ACKGenerator.generateAckResponse(connectorMessage.getRawData(), "AA", detailMessage);
resp = new Response(com.mirth.connect.userutil.Status.SENT, ack, statusMessage);
} else {
ack = ACKGenerator.generateAckResponse(connectorMessage.getRawData(), "AE", detailMessage);
resp = new Response(com.mirth.connect.userutil.Status.ERROR, ack, statusMessage, detailMessage);
}
return resp;
}
So I use ACKGenerator.generateAckResponse for creating an Ack and Response for send response at client. This work but only in destination and that's my problem.
If I get an error before destination (e.g. in filters, transformer, ...) I don't be able to stop execution and send an NACK with an explaination of the error and this is what I would like to do.
Am I wrong doing things in this way?
You can store a Response in the responseMap in any filters or transformers. Once you define a key in the responseMap, it should be available as a selection in the response drop down on the source tab of your channel (instead of picking a destination.)
Your current connector should stop processing a message with an ERROR status if you manually throw an exception after setting the desired value in the responseMap. If you are in a filter, you could also filter the message instead of throwing the exception.
If you are worried about an uncaught exception, you could initialize the responseMap variable with an "Unknown Error" message at the first point in the channel where your custom code is defined that affects messages directly (likely the source filter from your description, but could possibly be the pre-processor or attachment handler if you use those.) The expectation is that this would be replaced with a more descriptive error or a success if the message makes it all the way through to the end, but the channel will always have something to return.
There are filter and transformer in the "Source" tab. If your expecting an error there or on other destinations, you could try:
Adding a try-catch code block in your filter and transformer.
Use your custom code template function in your filter and transformer to catch the error or issue.
Create a separate channel that will receive the ACK/NACK which will be responsible in forwarding that message to the client.
In your try-catch code block or custom code template, use the method router.routeMessageByChannelId to forward the ACK/NACK to the other channel (step 3).
Note: You'll need to disable the default response in your original channel since you have the other channel that'll forward the ACK/NACK. You'll also need to consider if the client's machine expects a valid ACK/NACK immediately when they sent the HL7 message, depends on their setup.
I use the perform javascript call to perform an action on the server, like this:
subscription.perform('action', {...});
However, from what I've seen there seems to be no builtin javascript "success" callback, i.e. to let me know the action is concluded on the server's side (or possibly failed). I was thinking about sending a broadcast at the end of the action like so:
def action(data)
...do_stuff
ActionCable.server.broadcast "room", success_message...
end
But all clients subscribed to this "room" would receive that message, possibly resulting in false positives. In addition, from what I've heard, message order isn't guaranteed, so a previous broadcast inside this action could be delivered after the success message, possibly leading to further issues.
Any ideas on this or am I missing something completely?
Looking at https://github.com/xtian/action-cable-js/blob/master/dist/cable.js and , https://developer.mozilla.org/en-US/docs/Web/API/WebSocket#send(), perform just executes WebSocket.send() and returns true or false, and there is no way to know whether your data has arrived. (That is just not possible with WebSockets, it seems.)
You could try using just a http call (I recommend setting up an api with jbuilder), or indeed broadcasting back a success message.
You can solve the order of the messages by creating a timestamp on the server, and sending it along with the message, and then sorting the messages with Javascript.
Good luck!
Maybe what you are looking for is the trasmit method: https://api.rubyonrails.org/v6.1.3/classes/ActionCable/Channel/Base.html#method-i-transmit
It sends a message to the current connection being handled for a channel.
My problem is as follows: I have a TCP socket on which I asynchronously send messages based on a proprietary protocol. Upon receiving a response for a message I need to make sure that data gets sent back to the function that initially sent the message. The problem is I can only listen for responses on a "data" event on the socket (in this case in Node.js) and I have no way of easily determining which responses correspond to which messages.
Below is an example that I hope will give you an idea of what I am trying to accomplish.
function getTemperature (callback) {
socket.write(message);
// Good?
socket.on('data', callback);
}
function getVoltage (callback) {
socket.write(message);
// Other way to invoke callback?
}
getTemperature(function (err, temperature) {});
getVoltage(function (err, voltage) {});
socket.on('data', handleData function (data) {
// Somehow send data to correct function
}
One idea I had was registering multiple event handlers for the data event but this seems kind of wacky. What is the correct way to handle this?
When dealing with an asynchronous protocol, you would typically need to design the protocol so that each request has a unique ID that is included in the request data and gets sent back in the response. That way, you can receive responses out of order, and even receive unsolicited messages.
When you send a request, put the request ID in a list somewhere, along with a callback that will be called when the response arrives.
When you get a data event, append the raw data to a buffer, and then parse out only complete messages from the buffer, leaving incomplete messages for later completion. For each complete message parsed out, check if it has a request ID. If no, the message is unsolicited, so process it accordingly. Otherwise, look for the request ID in the list, and if found then call the callback associated with it.
In the meteor email documentation it is written
Email.send({
to: to,
from: from,
subject: subject,
text: text
});
Send an email. Throws an Error on failure to contact mail server or if
mail server returns an error
Should I assume this is done synchronously on the server side and that I should use a try/catch statement in order to know if the mail did sent successfully ? If so then I would have to assume that no catch means no error ?
Well you've answered this yourself:
It is sychronous
You would use try/catch in the case the mail server returns an error (if you've set MAIL_URL)
No catch means no error, again provided you've set MAIL_URL as the environmental variable.
Let's say I try to send to an authenticated transactional queue,
by calling msg.send(object,MessageQueueTransactionType.Single), message does not receive in transactional queue, no exception thrown.
What I want to accomplish is after sending, if message fail to send, perform some function and abort transaction, yet it doesn't throw exception, so I am unable to process it.
I am sending object from Web Application in local to local message queue.
My code is as follows in my web application:
MessageQueueTransaction mqTran=new MessageQueueTransaction();
try
{
using(System.Messaging.Message msg=new System.Messaging.Message(){
mqTran.Begin();
MessageQueue adminQ = new MessageQueue(AdminQueuePath);
MessageQueue msgQ = new MessageQueue(queuePath);
msgQ.DefaultPropertiesToSend.Recoverable = true;
msg.body = object;
msg.Recoverable=true;
msg.Label="Object";
msg.TimeToReachQueue=new TimeSpan(0,0,30);
msg.AcknowledgeType=AcknowledgeTypes.FullReachQueue;
msg.ResponseQueue=adminQ;
msg.AdministrationQueue=adminQ;
msgQ1.Send(msg,MessageQueueTransactionType.Single);
mqTran.Commit();
}
catch(Exception e)
{
mqTran.Abort();
//Do some processing if fail to send
}
It's not going to throw an exception for failure to deliver, only for failure to place on the queue. One of the points of message queueing is that the messages are durable so that you can take appropriate measures if delivery fails. This means you need to program another process to read the dead letter queue. The image below is taken from MSDN.
Because the entire process is asynchronous, your code flow is not going to be exception-driven the way your code block would like. Your transaction is simply the "sending transaction" in this workflow.
Recommendation: Check your message queue to find the messages, either in the outgoing queue or the transactional dead-letter queue.