Comments (16)
Hi @Swathy-Mothilal I have invited you as a collaborator to the private repo, is there anyone else I need to add too?
from office-js.
@rbays Thanks for reporting this issue, we have been able to reproduce it and it has been put on our backlog. We unfortunately have no timelines to share at this point.
Internal tracking id: Office: [4694943]
from office-js.
Thank you for sharing this issue @rbays! Connecting you @exextoc with who may be able to help.
from office-js.
@rbays We are unable to repro the issue locally. Can you please host your repro video and the har logs to a private repo, and grant permission to access it?
from office-js.
@rbays Thanks for sharing the repo. Could you please provide a video demonstrating the issue and logs? We need to understand the flow to be able to reproduce it.
from office-js.
@rbays Please provide a working manifest link also where you are able to repro the issue.
from office-js.
Hi, I don't have a manifest available to share, but I believe I have managed to isolate the issue. The below code will cause the issue on New Outlook for windows (there is no issue on old outlook or web)
the processMessageComposeEvent
event is in the manifest as a launch event as follows
<LaunchEvent FunctionName="processMessageComposeEvent" Type="OnNewMessageCompose"/>
Office.initialize = () => { };
type MailboxItem = Office.Item & Office.ItemCompose & Office.ItemRead &
Office.Message & Office.MessageCompose & Office.MessageRead &
Office.Appointment & Office.AppointmentCompose & Office.AppointmentRead;
function getContext() : Office.Context {
if (Office.context) {
return Office.context;
}
throw new Error();
}
function getMailbox() : Office.Mailbox {
const result = getContext().mailbox;
if (result) {
return Office.context.mailbox;
}
throw new Error();
}
function getMailboxItem() : MailboxItem {
const result = getMailbox().item;
if (result) {
return result;
}
throw new Error();
}
async function saveCustomProperties(customProps: Office.CustomProperties) : Promise<void> {
return new Promise((resolve, reject) => {
customProps.saveAsync((asyncResult) => {
if (asyncResult.status === Office.AsyncResultStatus.Failed) {
reject(asyncResult.error);
} else {
resolve();
}
});
});
}
function getItemCustomPropertiesAsync(): Promise<Office.CustomProperties> {
return new Promise((resolve, reject) => {
getMailboxItem().loadCustomPropertiesAsync((asyncResult) => {
if (asyncResult.status === Office.AsyncResultStatus.Failed) {
reject(asyncResult.error);
} else {
resolve(asyncResult.value);
}
});
});
}
async function setItemCustomPropertyAsync(key: string, value: string): Promise<void> {
const customProps = await getItemCustomPropertiesAsync();
customProps.set(key, value);
return saveCustomProperties(customProps);
}
async function processMessageComposeEvent(): Promise<void> {
let x = 0;
const intervalID = setInterval(() => {
x += 1;
if (x >= 40) {
window.clearInterval(intervalID);
} else {
setItemCustomPropertyAsync('test_key_iterator', x.toString());
}
}, 500);
}
export default processMessageComposeEvent;
The issue seems to be some kind of race condition between customProps.SaveAsync
and whatever is happening with the attachment being saved in office.
The code above just calls that method every half a second for the first 20 seconds when you start composing a new email.
By opening a new email, and then attaching some small attachments withing the first 5-10 seconds of having the message open I have been able to consistently reproduce the issue.
Please let me know if you need any more help to replicate the issue
from office-js.
@rbays , Thanks for sharing the code snippet. In your code, the processMessageComposeEvent function sets custom properties in a loop with a 500ms interval. If the attachments are being saved at the same time, there might be a conflict or timing issue that causes the attachments not to be removed properly. To avoid this race condition, could you please wait for Attachments to be Saved. Ensure that the attachments are fully saved before starting the custom property setting operations.
Here is a code snippet, that can help you.
async function waitForAttachmentsToBeSaved(): Promise {
return new Promise((resolve) => {
const checkAttachments = () => {
const attachments = getMailboxItem().attachments;
if (attachments.every(attachment => attachment.isInline || attachment.isSaved)) {
resolve();
} else {
setTimeout(checkAttachments, 100);
}
};
checkAttachments();
});
}
Please let me know if you have any queries.
from office-js.
Hi @Swathy-Mothilal ,
I don't have the isSaved
property available to me, I have upgraded the package https://www.npmjs.com/package/@types/office-js to 1.0.401 (which is currently the latest) and only have the following props available on the AttachmentDetails
interface that is returned.
Could you please advise if I should be using a different package to access this property?
Further, even if this does fix my issue, I believe that this will cause issues for others in the future, this is only an issue on New outlook (not OWA or old outlook) and means that every time someone saves a custom prop, they run the risk of breaking attachments. My example runs on a loop to ensure I can recreate the issue consistently, but when I initially encountered the issue, it was happening sporadically during the normal course of usage. As such I believe that this is a bug that should be fixed by the office-JS team
from office-js.
@rbays Few observations for your handler function in the code that you shared.
- event.completed() is not being called in the handler, without that function will not work properly.
- The handler code is returning a promise that platform can't wait for. The handler function should follow the rules mentioned at https://learn.microsoft.com/en-us/office/dev/add-ins/outlook/autolaunch#event-based-activation-behavior-and-limitations
Can you create a repro script in script lab, to help repro this.
from office-js.
Hi @rkpathak ,
- I have amended the process event to call the event.completed method below, though it doesn't make a difference and still has issues in the same way
- I cannot see anything relevant in the section you linked, but do you mean that the function should not be asynchronous?
async function processMessageComposeEvent(event: any): Promise<void> {
let x = 0;
const intervalID = setInterval(() => {
x += 1;
if (x >= 40) {
window.clearInterval(intervalID);
} else {
setItemCustomPropertyAsync('test_key_iterator', x.toString());
if (x === 39) {
event.completed();
}
}
}, 500);
}
from office-js.
@rbays Can you create a repro script in script lab and share the link, to help repro this.
from office-js.
@rkpathak I have created a script in script lab, however I have not been able to repro the issue this way because as far as I can tell, script lab does not run on new outlook.
I took an existing template and replaced the main function with the exact code from the example that I provided earlier.
I hope this helps.
Here are the segments of the script:
Script
$("#wreck-it").on("click", processMessageComposeEvent);
type MailboxItem = Office.Item &
Office.ItemCompose &
Office.ItemRead &
Office.Message &
Office.MessageCompose &
Office.MessageRead &
Office.Appointment &
Office.AppointmentCompose &
Office.AppointmentRead;
function getContext(): Office.Context {
if (Office.context) {
return Office.context;
}
throw new Error();
}
function getMailbox(): Office.Mailbox {
const result = getContext().mailbox;
if (result) {
return Office.context.mailbox;
}
throw new Error();
}
function getMailboxItem(): MailboxItem {
const result = getMailbox().item;
if (result) {
return result;
}
throw new Error();
}
async function saveCustomProperties(customProps: Office.CustomProperties): Promise<void> {
return new Promise((resolve, reject) => {
customProps.saveAsync((asyncResult) => {
if (asyncResult.status === Office.AsyncResultStatus.Failed) {
reject(asyncResult.error);
} else {
resolve();
}
});
});
}
function getItemCustomPropertiesAsync(): Promise<Office.CustomProperties> {
return new Promise((resolve, reject) => {
getMailboxItem().loadCustomPropertiesAsync((asyncResult) => {
if (asyncResult.status === Office.AsyncResultStatus.Failed) {
reject(asyncResult.error);
} else {
resolve(asyncResult.value);
}
});
});
}
async function setItemCustomPropertyAsync(key: string, value: string): Promise<void> {
const customProps = await getItemCustomPropertiesAsync();
customProps.set(key, value);
return saveCustomProperties(customProps);
}
async function processMessageComposeEvent(): Promise<void> {
let x = 0;
const intervalID = setInterval(() => {
x += 1;
if (x >= 40) {
window.clearInterval(intervalID);
} else {
setItemCustomPropertyAsync("test_key_iterator", x.toString());
console.log(x);
}
}, 500);
}
HTML
<section class="ms-font-m">
<p class="ms-font-m">This sample saves custom props a bunch to try to break attachments</p>
<p><b>Required mode</b>: Compose</p>
</section>
<section class="samples ms-font-m">
<h3>Try it out</h3>
<ol>
<li>click the button</li>
<br>
<li>add some attachments within 20 seconds</li>
<br>
<li>watch them break</li>
</ol>
<div class="ms-TextField">
<button id="wreck-it" class="ms-Button">
<span class="ms-Button-label">I'm gonna wreck it!</span>
</button>
</section>
CSS
section.samples {
margin-top: 20px;
}
section.samples .ms-Button, section.setup .ms-Button {
display: block;
margin-bottom: 5px;
margin-left: 20px;
min-width: 80px;
}
Libraries
https://appsforoffice.microsoft.com/lib/1/hosted/office.js
@types/office-js
[email protected]/dist/css/fabric.min.css
[email protected]/dist/css/fabric.components.min.css
[email protected]/client/core.min.js
@types/core-js
[email protected]
@types/[email protected]
from office-js.
@rkpathak is there any update or timeline on this?
from office-js.
Hi @rbays, apologies for the delay. I was able to reproduce this issue on the New Outlook, however as you mentioned this is very intermittent. Can you briefly elaborate the use case you are trying to address? If your add-in depending on attachments being saved or removed so that you can subsequently save the custom properties, you can consider listening to the OnMessageAttachmentsChanged event instead of doing so after intervals of 500ms?
from office-js.
Hi @kumarshrey-msft, the example I gave here isn't my actual use case, it's an example I created to help to hit the problem with more consistency to help you debug the problem.
In our actual usage we are storing a custom property on the message customProps when the user clicks a button in our taskpane to signify how the message should be processed on send, and also we are saving another custom prop during the messagecompose event to keep reference to the message.
The problem we have is that if the user happens to add an attachment to the email close to either of these events happening, there is a chance of the attachments breaking, which our QA team found, and managed to replicate about 1/10 times when trying.
As far as I can tell at the moment in new outlook, if you ever want to save message customProps, and the user wants to add an attachment, there is a chance that these 2 actions will clash and break the attachments for the user.
from office-js.
Related Issues (20)
- body.clear() not working for content controls HOT 3
- How to make slide active Or How to insert image using index HOT 4
- Addin sample not showing in new look outlook and browsers. HOT 5
- Identifying Usage of New Outlook in Office-js Add-ins HOT 1
- Not able to sideload outlook addin. in macbook there is no option to add the manifest file HOT 5
- Inserting Signature with the OnMessageSend event duplicates the signature
- The identity API is not supported for this add-in in online Word HOT 2
- Excel Online: calculation state can get stuck in Pending state when workbook contains charts HOT 3
- IP Address Range Needed for Microsoft Office Add-in Validation Process
- Office API messageParent Outlook on android doesn't work
- NAA: Unable to acquire access token for event-based activation (onMessageSend) HOT 2
- Outlook addin using Bootstrap modal or offcanvas bleeds through on Mac version of Outlook. Classic and New Outlook for Mac. HOT 2
- [Word API] Document.compare: ability to specify Original and Revised document?
- Outlook NAA issue: "Something went wrong. [7q6cl]" Error HOT 5
- Web Outlook provides improper attachment data if attachment is still uploading to the email HOT 2
- [Question] Is it safe to use `CustomFunctions.delayinitialization()`
- New Outlook - emails stuck in outlook at queued or draft status HOT 3
- context.application.createDocument works only first time HOT 1
- WorkBook level Define name is getting corrupted while reopening excel using base64
- In Outlook, getAllInternetHeadersAsync works on an item in the Inbox, but not the sent folder
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from office-js.