mongodb / stitch-js-sdk

MongoDB Stitch JavaScript SDK
Apache License 2.0
113 stars 67 forks source link

Handling CouldNotLoadPersistedAuthInfo Error #174

Closed chadokruse closed 6 years ago

chadokruse commented 6 years ago

I'm trying to figure out how to handle/guard against an intermittent error I'm seeing on clients. I'm running mongodb-stitch-browser-sdk: 4.0.14 in a Vue project.

The complete error is: (CouldNotLoadPersistedAuthInfo): failed to load stored auth information for Stitch

Here's what my initial isolation steps flushed out:

  1. Seems to mostly appear on Mobile Safari (11 and 12), but Firefox has popped up as well (62 - one behind current).
  2. Error in question is not captured by catch statement - there is no stacktrace
  3. Doesn't appear to be a disabled cookies issue. Prior to initializing Stitch I check for cookies, and those errors are being handled as expected by my catch statement.
  4. I can't reproduce locally (sorry)

Summarized code:

// My Vue method. This is called in the created lifecycle event.
methods: {
    initializeStitchAndLogin: function() {
      Stitch.initializeDefaultAppClient('insights-xavlz');

      const client = Stitch.defaultAppClient;
      return client.auth.loginWithCredential(new AnonymousCredential())
        .then(() => {
          this.stitchClientObj = client; // Note - Not currently using this
          return client;
        })
        .then(clientObj => {
          // Fetch data from Stitch
          // These do not get called when error appears - as expected
          this.getInsightsFromStitch(clientObj, 0);
          this.getUserDataFromStitch(clientObj, 0);
        })
        .catch(error => {
          // CouldNotLoadPersistedAuthInfo error not captured
          // Alert to client works on all errors except CouldNotLoadPersistedAuthInfo
        });
    },
  // Truncated for brevity

Any ideas? Something to do with localstorage?

I did see the error mentioned in the specs doc, but not in the troubleshooting faq

Not sure if this closed issue is related.

Full code can be found here. Production site here.

Thanks in advance for the help! Loving Stitch so far.

adamchel commented 6 years ago

Hi @chadokruse , apologies for the late response, this must have slipped under our radar. Glad you're enjoying Stitch so far!

The only place where CouldNotLoadPersistedAuthInfo is thrown is when the StitchAppClient is first initialized and the CoreStitchAuth constructor is called: (see https://github.com/mongodb/stitch-js-sdk/blob/master/packages/core/sdk/src/auth/internal/CoreStitchAuth.ts#L116)

This means the error is happening not on login, but in your call to Stitch.initializeDefaultAppClient. We unfortunately aren't exposing the actual exception you get there, but we can change that in a future release.

For now, if it's possible for you, could you add a console.log(e) or some other code to the mongodb-stitch-core-sdk dependency that will give us more information about the underlying error where the CouldNotLoadPersistedAuthInfo error is thrown? In your project, you would want to add this log statement right before the throw in the file node_modules/mongodb-stitch-core-sdk/dist/cjs/auth/internal/CoreStitchAuth.js (replacing cjs with umd if you're using Stitch JS SDK < 4.1.0 or esm if you're using our ES6 modules), and rebundle your project.

The next time the error intermittently happens, you should get a logged error. Let me know what you see and we can debug further. If you need any assistance with this or that doesn't make sense, please let me know.

chadokruse commented 6 years ago

Thanks @adamchel. Turns out the CouldNotLoadPersistedAuthInfo issue was Vue-related. The way I had it, the client wasn't necessarily initialized prior to the login attempt.

In case it helps others using Stitch with Vue, it appears running initializeDefaultAppClient in the beforeCreate hook and the rest in the created hook solves the issue (code below).

I'll go ahead and close this. I'm still working through some other odd intermittent issues (auth related, e.g. LoggedOutDuringRequest), but if I can't get them figured out I'll open a new ticket. Thanks again!

  beforeCreate: function() {
      Stitch.initializeDefaultAppClient(stitchAppId);
  },

  created: function() {
      this.initializeStitchAndLogin();
  }, 

  methods: {
    initializeStitchAndLogin: async function() {
      try {
        await this.stitchInit();
        await this.stitchLogin();
        this.stitchGetInsights(0);
        this.stitchGetUserData(0);
      } catch (error) {
        // handle error
      }
    },
  },

  stitchInit: async function() {
      // Save Stitch client as Vue data object
      if (!Stitch.hasAppClient(stitchAppId)) {
        // Note - this should never be called as Stitch.init... occurs in the beforeCreate lifecycle hook
        // thus, hasAppClient should always be true
        this.stitchClientObj = await Stitch.initializeDefaultAppClient(stitchAppId);
      } else {
        this.stitchClientObj = await Stitch.defaultAppClient;
      }
    },