Outlook email sent despite e.Cancel set in the Send event

Add-in Express™ Support Service
That's what is more important than anything else

Outlook email sent despite e.Cancel set in the Send event
 
Subscribe
degree




Posts: 34
Joined: 2010-07-27
Hello devs!
In our flow we are cancelling sending the email via Outlook:


private void AdxOutlookEvents_ItemSend(object sender, ADXOlItemSendEventArgs e)
{
  ...
  e.Cancel = true;
  ...
}


And this works. However it happened for one user, that when an error in our flow occurred (after e.Cancel was set) the email was send via Outlook anyway. Locally I tried throwing such error in different places but could not reproduce it. Is this possible? It might be that I am overlooking something, but I wanted to confirm if there is any possibility of this Cancel flag being overridden (by some other piece of code).
Posted 08 Sep, 2017 09:18:06 Top
Andrei Smolin


Add-in Express team


Posts: 14137
Joined: 2006-05-11
Hello,

The Cancel flag is only checked if the event handler returns correctly. That is, you need to wrap your code in a try/catch block to let the event handler complete normally.

Regards from Belarus (GMT+3),

Andrei Smolin
Add-in Express Team Leader
Posted 11 Sep, 2017 06:11:14 Top
degree




Posts: 34
Joined: 2010-07-27
Hi Andrei
Thanks for info. Our entire ItemSend handler is wrapped in try/catch/finally. Can you think of any other cause of this behavior?
Posted 11 Sep, 2017 06:19:25 Top
Andrei Smolin


Add-in Express team


Posts: 14137
Joined: 2006-05-11
Could you please provide a call stack for that exception?

Regards from Belarus (GMT+3),

Andrei Smolin
Add-in Express Team Leader
Posted 11 Sep, 2017 06:58:06 Top
degree




Posts: 34
Joined: 2010-07-27
This is the stack trace:

System.Runtime.InteropServices.COMException (0x8004010F): The message you specified cannot be found.
at Microsoft.Office.Interop.Outlook.NameSpaceClass.GetItemFromID(String EntryIDItem, Object EntryIDStore)
at SendExtender.uploader_UploadComplete(String id1, String id2, IList`1 data)
at Uploader.UploadThread() in Uploader.cs:line 167

After we do some uploads on a separate thread, then we are back to "main" thread in the uploader_UploadComplete event handler. And here we try to find the mail message that we are working with.
Posted 12 Sep, 2017 01:03:39 Top
Andrei Smolin


Add-in Express team


Posts: 14137
Joined: 2006-05-11
Hello Andrzej,

The exception seemingly doesn't relate to the ItemSend event.

You won't find an item using its EntryID previously stored if the item is moved to another folder. This is because the EntryID contains the full folder path to the item.

Also, I don't understand whether the code that fails works on the main thread or not. If not, you should redesign your code so that it only accesses the Outlook object model (= any object model in Office) on the main thread.

Regards from Belarus (GMT+3),

Andrei Smolin
Add-in Express Team Leader
Posted 13 Sep, 2017 05:51:26 Top
Andrei Smolin


Add-in Express team


Posts: 14137
Joined: 2006-05-11
Also, you sent us your AddinModule.cs in relation to your other issue. In this code version, in the ItemSend event I see that e.Cancel = true is the last line: that is, if there's an exception, your code won't set e.Cancel=true.

Regards from Belarus (GMT+3),

Andrei Smolin
Add-in Express Team Leader
Posted 13 Sep, 2017 05:57:46 Top
degree




Posts: 34
Joined: 2010-07-27
Thanks Andrei. The code that fails - it is and event handler, attached on the main thread, but the event itself is triggered in a separate threa. I guess that means it runs on the separate thread too. So should we use some kind of InvokeRequire/Invoke pattern to run it on the main thread? Can you point to some docs/article that explains how do we reach the main thread in such an addin?

Regarding e.Cancel - yes it is set at the end, but according to user report and the log file the exception occurred in a piece of code that can handle it. Also if it happened just above that line we would get it in the log file. Anyway we applied a couple of tweaks to mitigate the problem. I consider this part solved for now.
Posted 13 Sep, 2017 06:10:05 Top
Andrei Smolin


Add-in Express team


Posts: 14137
Joined: 2006-05-11
degree writes:
So should we use some kind of InvokeRequire/Invoke pattern to run it on the main thread?


Yes. We recommend using the SendMessage/OnSendMessage machinery where the OnSendMessage event always occurs on the main thread. That is, you call SendMessage passing it a message - a unique integer >= 1024 - and when the OnSendMessage event is triggered you filter out the message and perform the action.

degree writes:
I consider this part solved for now.


Thank you for letting me know.

Regards from Belarus (GMT+3),

Andrei Smolin
Add-in Express Team Leader
Posted 13 Sep, 2017 06:56:57 Top
degree




Posts: 34
Joined: 2010-07-27
Not sure if I understood. We attach the send handler:


this.AdxOutlookEvents.ItemSend += new AddinExpress.MSO.ADXOlItemSend_EventHandler(this.AdxOutlookEvents_ItemSend);


And then the flow is like this:

1. Outlook "Send" is clicked -> we go into AdxOutlookEvents_ItemSend
2. Inside this handler we start a new thread and do some background work
3. When that thread is done we want to update the email that triggered it (so execute a method back on the main thread)
Posted 13 Sep, 2017 07:05:02 Top