4
votes

Our production customers are struggling with the following error: Office JS API doesn't return user identity token and this blocks the whole usage of our Add-In.

Error which we see in logs:

{
    "name": "AccessRestricted",
    "message": "Internal protocol error: '-2147467259'.",
    "code": 9017
}

Sometimes it appears when a laptop wakes up after sleep mode, sometimes not.

Also, the following error appears sometimes (but not every time when AccessRestricted error is seen) in Office JS API when our code executes get user identity token async:

"Unable to get property 'Execute' of undefined or null reference",
"number": -2146823281,
"stack": 
    "TypeError: Unable to get property 'Execute' of undefined or null reference
     at n.prototype.execute (https://appsforoffice.microsoft.com/lib/1... (truncated by our logging system)

Outlook version is 16.0.8528.2147 and add-in was pinned. P.S. Office JS API was initialized, it's not a root cause of this problem.

Here are the pieces of code:

sfMailApp.OfficeManager.prototype.getCallbackTokenAsync = function () {
    var item = this.getItem();

    return !item.isFake ? this._loadItemAsync(Office.context.mailbox, 'getCallbackTokenAsync') : sfMailApp.utils.resolveDeferred('');
};

sfMailApp.OfficeManager.prototype.getIdentityTokenAsync = function (force) {
    var ls = getLocalStorage();
    var lastUpdateIdentityTokenTimestamp = ls.getItem('identityTokenUpdate');
    var cachedIdentityToken = ls.getItem('identityToken');

    var lastUpdateIdentityTokenDifference = !sfMailApp.utils.isNullOrEmpty(lastUpdateIdentityTokenTimestamp) ? (new Date().getTime() - parseInt(lastUpdateIdentityTokenTimestamp)) : null;

    if (sfMailApp.utils.isNullOrEmpty(cachedIdentityToken) || cachedIdentityToken === 'null' || sfMailApp.utils.isNullOrEmpty(lastUpdateIdentityTokenDifference) || force ||
        (lastUpdateIdentityTokenDifference / (1000 * 60)) > sfMailApp.settings.identityTokenUpdateIntervalMinutes) {
        var deferred = $.Deferred();

        var item = this.getItem();

        if (!item.isFake) {
            sfMailApp.analytics.trackEvent('LoadUserIdentityTokenAsync', 'Start', {
                user: sfMailApp.mailService.userEmail
            });

            this._loadItemAsync(Office.context.mailbox, 'getUserIdentityTokenAsync').done(function (token) {
                ls.setItem('identityTokenUpdate', new Date().getTime());
                ls.setItem('identityToken', token);
                sfMailApp.sessionManager.setIdentityToken(token);
                deferred.resolve(token);
            }).fail(function (err) {
                ls.setItem('identityTokenUpdate', null);
                ls.setItem('identityToken', null);
                sfMailApp.analytics.trackEvent('LoadUserIdentityTokenAsync', 'Fail', {
                    user: sfMailApp.mailService.userEmail,
                    message: err ? JSON.stringify(err) : 'null'
                });
                deferred.reject(err);
            });
        } else {
            sfMailApp.analytics.trackEvent('Item', 'Empty', {
                user: sfMailApp.mailService.userEmail,
                message: 'Error while getting identity token - inbox item is empty'
            });
            sfMailApp.sessionManager.setIdentityToken(cachedIdentityToken);
            return sfMailApp.utils.resolveDeferred(cachedIdentityToken);
        }

        return deferred.promise();
    } else {
        sfMailApp.sessionManager.setIdentityToken(cachedIdentityToken);
        return sfMailApp.utils.resolveDeferred(cachedIdentityToken);
    }
};


sfMailApp.OfficeManager.prototype._loadItemAsync = function (obj, name) {

    if (sfMailApp.utils.isCommands() && sfMailApp.isCommandsMagicPixel) {
        return sfMailApp.utils.rejectDeferred({
            message: 'Async Office JS API should not be called in Commands while inserting MagicPixel'
        });
    }

    var deferred = $.Deferred();

    var maxAttempCount = 5;
    var attempInterval = 1000;
    var attempCount = 0;
    var _this = this;

    function checkResult(asyncResult) {
        var processFunc = function () {
            try {
                if (_this._checkProperyExists(obj, name)) {
                    obj[name](checkResult);
                } else {
                    checkResult(null);
                }
            } catch (e) {
                if (name !== 'loadCustomPropertiesAsync' && name !== 'getCallbackTokenAsync') {
                    sfMailApp.analytics.trackException(e, name + '.Fail', {
                        user: sfMailApp.mailService.userEmail,
                        error: e ? JSON.stringify(e) : null
                    });
                }
                checkResult(null);
            }
        }

        if ((sfMailApp.utils.isNullOrEmpty(asyncResult) || asyncResult.status !== Office.AsyncResultStatus.Succeeded) && attempCount < maxAttempCount) {
            attempCount++;
            if (attempCount <= 1) {
                processFunc();
            } else {
                setTimeout(processFunc, attempInterval);
            }
        } else {
            if (asyncResult && asyncResult.status === Office.AsyncResultStatus.Succeeded) {
                deferred.resolve(asyncResult.value);
            } else {
                var params = {
                    user: sfMailApp.mailService.userEmail
                };
                if (asyncResult) {
                    params.status = asyncResult.status;
                    params.value = asyncResult.value;
                    params.error = JSON.stringify(asyncResult.error);
                }

                if (name !== 'loadCustomPropertiesAsync' && name !== 'getCallbackTokenAsync') {
                    sfMailApp.analytics.trackException(new Error(name + '.Fail'), '', params);
                }
                deferred.reject(asyncResult);
            }
        }
    }

    var inboxItem = this.getItem();

    if (obj && !obj.isFake && !inboxItem.isFake) {
        checkResult(null);
    } else {
        deferred.resolve({});
    }

    return deferred.promise();
};
1
Can you provide the code you're using that results in this error? - Marc LaFleur
@MarcLaFleur thank you for your prompt response, the code has been attached. - Sviatoslav Lobach
I'm not seeing where your referencing a method or property called Execute. Which line is it failing on? - Marc LaFleur
@Mark, please check the reference to the URL of the script. It's your Office JS API code appsforoffice.microsoft.com/lib/1... - Sviatoslav Lobach
I understand, but I'm still not clear which call into Office.js is triggering the error. - Marc LaFleur

1 Answers

0
votes

Thanks for letting us know, Sviatoslav. We are aware of the issue and are currently investigating it. We will update this answer once a fix has been identified!