OfficeDev / office-js

A repo and NPM package for Office.js, corresponding to a copy of what gets published to the official "evergreen" Office.js CDN, at https://appsforoffice.microsoft.com/lib/1/hosted/office.js.
https://learn.microsoft.com/javascript/api/overview
Other
685 stars 95 forks source link

Error shown to user (and fetch call cancelled) if onAppointmentSend event execution happens when other launch event(s) are running on an appointment #4669

Open pepso opened 4 months ago

pepso commented 4 months ago

Expected behavior

If there is an existing launch event execution taking place, the Outlook would either queue up the execution of onAppointmentSend, or otherwise not showing an error to the user. Maybe segregate the fetch calls so they don't interfere each other if that's the underlying reason?

Our fetch end point is wrapped around exception handling so definitely we should not show an error like this to the user when we call event.completed({..}) successfully: image

Current behavior

An add-in with launch events for recipient/time/recurrence changes is executing the event for ~500 ms and on slow computer/network up to few seconds.

There can be multiple launch events (non-onAppointmentSend) being processed in parallel without a problem.

When triggering onAppointmentSend launch event during the non-onAppointmentSend launch events execution, an error is shown to the user (and the fetch call gets cancelled). image

This issue occurs only in New Outlook and Outlook OWA, but not on Classic Outlook.

Steps to reproduce

  1. Have an add-in which executes long running process on appointment launch events (for us it's sub-second, or up to few seconds to ease the replication of the issue).
  2. Have an onAppointmentSend launch event code which calls API/end point (at least this is the case for us)
  3. Click "send" appointment meanwhile the non-onAppointmentSend is still executing and see the error (and cancelled api calls)

Provide additional details

We are not able to figure out why the response to event.completed({...}) is not shown to the user despite calling it and instead they are greeted with generic error.

Context

Users, especially ones on slow computers / slow internet connection get "Add-in is preventing this email from being sent" when they attempt to send an appointment.

Useful logs

Here's the logging of the sequence of onReady, olkAppointmentTimeChanged, onAppointmentSend execution. As is evident from the logs when we get the error on UI, we have already responded with event.completed({...}), and then catch the exception from the API call to push it to console logs. image

Thank you for taking the time to report an issue. Our triage team will respond to you in less than 72 hours. Normally, response time is <10 hours Monday through Friday. We do not triage on weekends.

pepso commented 4 months ago

After further thinking the issue there's another way of looking at this non-descriptive error message:

Calling event.completed({allowEvent: false, errorMessage: 'This meeting is…', commandId: 'openPanel', cancelLabel: 'Custom Label'} renders the errorMessage when the onAppointmentSend is the only launch event being executed.

On the other hand, if there are other launch events being executed, the completed function's errorMessage does not get rendered to the warning dialog for the user (and ongoing fetch call gets cancelled).

rkpathak commented 4 months ago

@pepso It's not clear what API call you are making that is getting cancelled and from which event handler. Can you give clear steps that we can follow to reproduce this issue. Or share sample addin code/script lab code link that we can use to reproduce the issue.

pepso commented 4 months ago

Hi @rkpathak,

While I was compiling you a minimum failing example it started to look like the network error is not the culprit, but a symptom on how the action sequencing are handled (and how they fail).

When running below example do these steps on the New Outlook UI:

  1. Open an existing event in edit mode
  2. Trigger launch event(s) with "All day" toggle
  3. Click send (within 100's of milliseconds from the toggle)
  4. Observe dialog error text "Add in is preventing this email from being sent." (ERROR)
  5. Close the dialog
  6. Wait a couple of seconds and click send
  7. Observe dialog error text "Show custom error message." (OK)
  8. Comment out the row 15, fake network delay from the sendAction
  9. Trigger launch event(s) with "All day" toggle
  10. Click send (within 100's of milliseconds from the toggle)
  11. Observe dialog error text "Show custom error message." (OK)
            <LaunchEvents>
              <LaunchEvent Type="OnAppointmentSend" FunctionName="sendAction" SendMode="PromptUser" />
              <LaunchEvent Type="OnNewAppointmentOrganizer" FunctionName="action"/>
              <LaunchEvent Type="OnAppointmentAttachmentsChanged" FunctionName="action" />
              <LaunchEvent Type="OnAppointmentAttendeesChanged" FunctionName="action" />
              <LaunchEvent Type="OnAppointmentTimeChanged" FunctionName="action" />
              <LaunchEvent Type="OnAppointmentRecurrenceChanged" FunctionName="action" />
              <LaunchEvent Type="OnAppointmentOrganizer" FunctionName="action" />
            </LaunchEvents>

And here's the code of commands.js:

Office.onReady(() => {});

function fakeNetworkCallDelay(millisec) { 
  return new Promise(resolve => { 
      setTimeout(() => { resolve('') }, millisec); 
  }) 
}

const action = async(event) => {
  await fakeNetworkCallDelay(500);
  event.completed();
}

const sendAction = async(event) => {
  await fakeNetworkCallDelay(2000); // If you comment this row out, you get the "Show custom error message" message on the dialog popup.
  event.completed({"allowEvent":false,"errorMessage":"Show custom error message."});
}

window.action = action;
window.sendAction = sendAction;
kumarshrey-msft commented 3 months ago

Hi @pepso, can you please confirm whether you are having multiple launch event add-ins?

pepso commented 3 months ago

@kumarshrey-msft when I ran the tests I had 2 launch event add-ins (or maybe 3 when you count the side-loaded add-in). It is my belief the client who reported the error to us originally has only our Add-in running with launch events.

exextoc commented 3 months ago

@pepso 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: [292838]

pepso commented 2 months ago

Hi @exextoc / @kumarshrey-msft,

We understand there's no time line commitments from the team to release these fixes, but are you able to give us a rough idea how high / low in the priority order this issue currently is?

This is blocking a major deployment of our Add-in until client's users are not slammed non-descriptive errors boxes on their screens like this.

pepso commented 2 months ago

@exextoc and @kumarshrey-msft

Meanwhile we are waiting for the bug fix we have attempted workarounds to the bug. During the search we identified a further issue with the LaunchEvent sequencing in new/web Outlooks.

Here's the 2 scenarios which are causing issues to our users in terms of error/warning boxes not related to our Add-in but Outlook itself: image

For the scenario with Red Error box, we are able to do polling in the x-event executions to exclude ~50% of the errors by forcing the original action to wait until the (potentially ongoing) onSend action calls the event.completed({}).

For the right hand scenario, the yellow warning turning into a timeout, we have absolutely no control or ways to work around the bug. We assume onSend function's "event" (which we use to call the event.completed({...})) gets overwritten by the latter launch event's "event" which is triggered by user/automated process after the "send" is clicked. (Think this way: User sends the appointment, and while waiting the send processing, the user changes the time/recurrence/attendees => Yellow warning / timeout).

Are these 2 behaviors the one and same bug, or should I raise second issue for the right hand scenario?

Here's a bit speculation from the reasons from our point-of-view: The yellow error our users experience seems similar to this issue: https://github.com/OfficeDev/office-js/issues/4645

In our instance the onSend validation takes <1 second (~300-500ms), and our working assumption is that our client's environment sometimes trigger automatic LaunchEvents (setSignature, other Add-ins, or something in these lines.) and then depending on the sequence the Add-ins/operations get executed in their environment, might then cause our onSend event to never complete.