Skip to content

Report a problem:

Problems can be reported via Microsoft Teams in your team channel within the "IT - Codey" team.

Please include the following information:

Report type:
Docs problem report a bug instead →
Path:
/vnext/docs/core/modules/global-error-handler.html
Message:

DESCRIBE THE PROBLEM BEFORE SUBMITTING TO CODEY

Global Error Handler

This library provides a way to handle fetch errors automatically. Errors will also be tracked in Application Insights when provided.

WARNING

There is no out-of-the-box support for Axios yet. Please contact the Codey team for more information.

Dependencies

Usage

Installation

To have errors handled, global error handling needs to be set up using setupGlobalErrorHandler, providing the localizedRouter and optional options (so if you don't want a certain error to be handled, it can be omitted from the options).

The available options are in line with how we as Codey want to see those errors handled from a UX standpoint:
The not found, forbidden, and unauthorized errors will be redirected to their corresponding pages.
The internal server error is provided as a callback, which allows for more flexibility in how this is handled. We found that this can differ from app to app.
For a back-office application, we recommend using a toast to show that something went wrong. For a public-facing application, it might be better to show a more generic error page.

Make sure to use the localizedRouting instance from the @xerius/codey-core package to navigate to the error pages. For more information on how to use this, please refer to the localized routing documentation.

INFO

The registration can also be done in the main.ts file; just make sure it's done after the router initialization.

Be aware that this will prevent usage of composables like useToast(), as they need to be used within a Vue setup method.

vue
<script setup lang="ts">
import { useToast } from "primevue/usetoast";
import { useApplicationInsights } from "@xerius/codey-core/modules/application-insights";
import { setupGlobalErrorHandler } from "@xerius/codey-core/modules/global-error-handler";

const toast = useToast();
setupGlobalErrorHandler(
  localizedRouting,
  {
    notFoundRoute: { name: "NotFound" },
    forbiddenRoute: { name: "Forbidden" },
    unauthorizedRoute: { name: "Unauthorized" },
    internalServerErrorAction: () => {
      toast.add({
        severity: "error",
        summary: "Internal Server Error",
        detail: "Oeps, er ging iets mis. Probeer later nog eens ...",
        life: 3000,
      });
    },
  },
  useApplicationInsights
);
</script>
ts
import { createI18n } from "vue-i18n";
import { registerI18nMessageLoader } from "@xerius/codey-core/modules/i18n";
import { useApplicationInsights } from "@xerius/codey-core/modules/application-insights"; 
import { registerI18nMessageLoader, postTranslationHandler } from "@xerius/codey-core/modules/i18n";
import { createLocalizedRouting } from "@xerius/codey-core/modules/localized-routing";
import { setupGlobalErrorHandler } from "@xerius/codey-core/modules/global-error-handler"; 
import { fetchTranslations } from "./api/translations.api";
import { localizedAppNames } from "./router/routes";
import App from "./App.vue";
import router from "@/router";

const i18n = createI18n({
  legacy: false,
  locale: "nl-be",
  fallbackLocale: "nl-be",
  globalInjection: true,
  postTranslation: postTranslationHandler,
});
registerI18nMessageLoader(i18n, fetchTranslations);

const localizedRouting = createLocalizedRouting(router, i18n, localizedAppNames);

setupGlobalErrorHandler(
  localizedRouting, 
  {
    notFoundRoute: { name: "NotFound" }, 
    forbiddenRoute: { name: "Forbidden" }, 
    unauthorizedRoute: { name: "Unauthorized" }, 
    internalServerErrorAction() {
      localizedRouting.pushLocalizedRoute("Oeps"); 
    }, 
  }, 
  useApplicationInsights 
); 

const app = createApp(App);
// ...

ApplicationInsights

You have the option of providing your Application Insights instance to the setupGlobalErrorHandler() function.

WARNING

Currently, the instance will only be used to call trackTrace() or trackException() in handleFetchError().
Other error handling will not make use of the provided Application Insights instance.

handleFetchError

To handle network failures automatically, you need to provide an error handler to the fetch calls. This can be easily done using the useFetch composable from the @vueuse/core library and providing it the handleFetchError as an error handler.

ts
import { useFetch } from "@vueuse/core";
import { useGlobalErrorHandler } from "@xerius/codey-core/modules/global-error-handler";

const globalErrorHandler = useGlobalErrorHandler();

const { data } = useFetch(url, {
  onFetchError(ctx) {
    return globalErrorHandler.handleFetchError(ctx);
  },
});

For now, we focus on the fetch API with useFetch from VueUse. Support for Axios can be provided upon request. If errors need to be handled in a specific way, you can omit this function and handle them manually.

useGlobalErrorStore

Along with the error handling, we store error data within the globalError store. This can be accessed to get extra information or perform specific error handling yourself when needed.

handleGlobalError

This is the error handling function used internally by handleFetchError and can be used to trigger error handling yourself.

This function is available on the globalErrorHandler instance retrieved by useGlobalErrorHandler.

Reset error state

If the error state is used to show or hide parts of your application, it will be necessary to reset this once a page navigation has occurred.

This can be easily done within the router configuration with the following:

router.ts
ts
import { useGlobalErrorStore } from "@xerius/codey-core/modules/global-error-handler";

router.beforeEach(() => {
  useGlobalErrorStore().$reset();
});

Custom State Layer

If your application does not depend on Pinia and you don't want to introduce this dependency purely for the global error handler, you can create your own custom state layer using, for example, a composable.

Pass your implementation that meets the GlobalErrorHandlerStore interface to the setupGlobalErrorHandler function.

Note

Creating your own store also means carrying the responsibility of implementing the necessary state management logic and functions like reset.

ts
import { reactive } from "vue";
import type { GlobalErrorState } from "@xerius/codey-core/global-error-handler";

const state = reactive<GlobalErrorState>({
  errorType: undefined,
  error: undefined,
});

export const useGlobalErrorState = () => {
  return state;
};
ts
import { createI18n } from "vue-i18n";
import { registerI18nMessageLoader } from "@xerius/codey-core/modules/i18n";
import { useApplicationInsights } from "@xerius/codey-core/modules/application-insights";
import { registerI18nMessageLoader, postTranslationHandler } from "@xerius/codey-core/modules/i18n";
import { createLocalizedRouting } from "@xerius/codey-core/modules/localized-routing";
import { setupGlobalErrorHandler } from "@xerius/codey-core/modules/global-error-handler";
import { useGlobalErrorState } from "@/use/useGlobalErrorState"; 
import { fetchTranslations } from "./api/translations.api";
import { localizedAppNames } from "./router/routes";
import App from "./App.vue";
import router from "@/router";

const i18n = createI18n({
  legacy: false,
  locale: "nl-be",
  fallbackLocale: "nl-be",
  globalInjection: true,
  postTranslation: postTranslationHandler,
});
registerI18nMessageLoader(i18n, fetchTranslations);

const localizedRouting = createLocalizedRouting(router, i18n, localizedAppNames);

setupGlobalErrorHandler(
  localizedRouting,

  {
    notFoundRoute: { name: "NotFound" },
    forbiddenRoute: { name: "Forbidden" },
    unauthorizedRoute: { name: "Unauthorized" },

    internalServerErrorAction() {
      localizedRouting.pushLocalizedRoute("Oeps");
    },
  },
  useApplicationInsights,
  useGlobalErrorState 
);

const app = createApp(App);
// ...

Report a problem:

Problems can be reported via Microsoft Teams in your team channel within the "IT - Codey" team.

Please include the following information:

Report type:
Docs problem report a bug instead →
Path:
/vnext/docs/core/modules/global-error-handler.html
Message:

DESCRIBE THE PROBLEM BEFORE SUBMITTING TO CODEY