How to tolerate failures when loading multiple Plasmic projects?

Hey guys - when loading multiple projects, is there a way for initPlasmicLoader and PlasmicRootProvider to fail more gracefully if given incorrect project information?

Right now, if any project has an incorrect id or token, the entire fetch fails with a 403. What I would prefer is that valid projects are returned, and invalid ones are reported as an error.

Hi @native_woodpecker, you can wrap the calls to fetchcomponentdata in a try catch, will that work for you?

That’s what we’re doing for now, but it still results in no Plasmic content loading at all if one project is incorrect.

Our use case is that we have a Plasmic project associated with an order in our back-end, and a user has access to any number of orders. We encountered the problem when a project token wasn’t saved correctly for a new order.

Plasmic rejecting the bad project token resulted in nothing loading for our user, instead of only the new project with the bad credentials.

Would you happen to have a snippet of code that I can take a look at to see how exactly the loading + later rendering is done?

Something to take care of is that after the loading fails, you’ll also want to make sure to avoid rendering a component that was never loaded

For generating the project list and setting up the PlasmicComponentLoader object:

const projectList = orders.filter(
  (o) => o.plasmicProject
).map((o) => ({
  id: o.plasmicProject.id
  token: o.plasmicProject.token
});

const PLASMIC = initPlasmicLoader({
  projects: projectList,
});

We then do fetchPages using the above config, and store the result in state. This is where we’re getting our 403 error because of bad project config.

    async function getPages() {
      try {
        const pages = await PLASMIC.fetchPages();
        setPlasmicPageList(pages);
      } catch (e) {
        // err handling here
      }
    }

We use the provided page data to dynamically generate a menu. When a user clicks on a link from that menu, we load our Container component that then retrieves the actual page data. PlasmicRootProvider wraps the Container and receives PLASMIC as its loader.

const pageData = await PLASMIC.maybeFetchComponentData(
  // menu link page info here
);

This is a bit abstracted, so let me know if any of that doesn’t make sense

Oh got it!

You can instead make a separate loader and fetchpages call for each project, would that work in your case? (You can also parallelize these) I can send an example snippet if helpful once I’m back at keyboard later on tonight

That’s potentially an option! I’d def like the example when you get a chance :slightly_smiling_face:

I just mean something along these lines, let me know if this works for you:

  const PLASMICS = projectsAndTokens.map(({ id, token }) =>
    initPlasmicLoader({
      projects: [
        {
          id,
          token,
        },
      ],
    })
  );
  const pagesByProject = Promise.allSettled(
    PLASMICS.map(async (PLASMIC) => {
      try {
        return await PLASMIC.fetchPages();
      } catch (err) {
        return [];
      }
    })
  );