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
682 stars 95 forks source link

Add-in crashes if another user causes changes in the add-in settings #4354

Open Stigjb opened 7 months ago

Stigjb commented 7 months ago

Background

A Word document is stored in Sharepoint. Two users have the same document open in word, with Auto-save enabled. The two users are using the same add-in. When one user takes an action that changes the settings via the Word.Setting API, the other user shortly after sees their instance of the add-in crash and reload, losing all local state.

Your Environment

Expected behavior

There should be a way to handle changes in add-in settings that happen on sync, without losing local state.

Current behavior

The add-in crashes and restarts without warning. Any local state, including console logs, disappears.

Steps to reproduce

Create a new Word document, stored in Sharepoint. Two different users should open the document at the same time in two separate instances of Word. Both users run the snippet below in Script Lab. One user clicks "Reset" and then "Increment" several times. The other user sees Script Lab crash and restart. If their dev tools or console happens to be open, it will close and not reopen.

Link to live example

name: Settings sync in shared file
description: Reproduce crash
host: WORD
api_set: {}
script:
  content: |
    $("#reset").on("click", () => tryCatch(reset));
    $("#increment").on("click", () => tryCatch(increment));

    const reset = async () => {
      Word.run(async (context) => {
        const { settings } = context.document;
        settings.add("foo", { times: 0 });
        context.sync();
      });
    };

    const increment = async () => {
      Word.run(async (context) => {
        const { settings } = context.document;
        const foo = settings.getItem("foo");
        foo.load("value");
        await context.sync();
        foo.value = { times: foo.value.times + 1 };
        await context.sync();
      });
    };

    async function tryCatch(callback) {
      try { await callback(); } catch (error) { console.error(error); }
    }
  language: typescript
template:
  content: |
    <button id="reset" class="ms-Button">
        <span class="ms-Button-label">Reset</span>
    </button>
    <button id="increment" class="ms-Button">
        <span class="ms-Button-label">Increment</span>
    </button>
  language: html
style:
  content: |-
    section.samples { margin-top: 20px; }

    section.samples .ms-Button, section.setup .ms-Button {
        display: block;
        margin-bottom: 5px;
        margin-left: 20px;
        min-width: 80px;
    }
  language: css
libraries: |
  https://appsforoffice.microsoft.com/lib/1/hosted/office.js
  @types/office-js

  office-ui-fabric-js@1.4.0/dist/css/fabric.min.css
  office-ui-fabric-js@1.4.0/dist/css/fabric.components.min.css

  core-js@2.4.1/client/core.min.js
  @types/core-js

  jquery@3.1.1
  @types/jquery@3.3.1

Context

We have published an add-in, and have received reports from our own customers, who have been unable to work concurrently on the same document using our add-in, because of actions that update settings.

microsoft-github-policy-service[bot] commented 7 months ago

Thank you for letting us know about this issue. We will take a look shortly. Thanks.

Searion commented 6 months ago

@Stigjb Thanks for reporting this. We create a work item (8923042) to track it. If anything updated we'll sync with you.

aorsten commented 4 months ago

@Searion We're also struggling with this - is there any progress to report?

This breaks collaboration within our add-in. Is this expected from your end - and if so, do you recommend against using settings vs. some other storage api?

Searion commented 4 months ago

@aorsten Sorry for the late response. We are still investigating the root cause. However, this scenario is quite complicated and we have not made any big progress. Befor we fix the bug, could you please try Document.properties.customproperties Api for storage?

aorsten commented 3 months ago

@Searion I have an addition to this issue, which could possibly be a different bug as well.

So we see the behavior described in this issue happen every time 2 users try to collaborate. In addition, sometimes, all stored settings are lost when this occurs. We have not been able to deduce what causes it, but the result is that the webextensions folder is deleted somehow from the .docx file.

I have a theory:

This is even worse than the issue reported above, because we are actually losing customer data because of this, which renders the settings API quite useless and dangerous to use. Are you able to put more priority into this? You are recommending the settings storage in your documentation, and it seems to me there are more and more companies/people taking up OfficeJS add-ins for commercial usecases. Being able to trust the Microsoft product should be pivotal.