Newer
Older
smart-home-server / webclient / src / composables / useGlobalErrorHandler.js
/**
 * Composable that wires up global error-catching surfaces.
 * Should be called once during app bootstrap (main.js).
 */
export function useGlobalErrorHandler(app) {
  const LOG_PREFIX = "[vue:error]";

  /**
   * 1. Vue runtime errors — render, watcher, lifecycle hooks, event handlers.
   *    This does NOT catch errors inside async functions (those are promises).
   */
  app.config.errorHandler = (err, instance, info) => {
    const message = err?.message || String(err);
    console.error(
      LOG_PREFIX,
      `Vue ${info}`,
      message,
      err?.stack || ""
    );
  };

  /**
   * 2. Unhandled promise rejections (fetch without catch, async function
   *    that throws and is not awaited, etc.)
   */
  window.addEventListener("unhandledrejection", (event) => {
    const reason = event.reason;
    const message = reason?.message || reason?.error?.message || String(reason);
    console.error(
      LOG_PREFIX,
      "Unhandled rejection:",
      message,
      reason?.stack || ""
    );
    event.preventDefault();
  });

  /**
   * 3. Global synchronous JS errors (script parse errors, runtime throws
   *    outside of Vue, etc.)
   */
  window.addEventListener("error", (event) => {
    const error = event.error;
    const message = error?.message || event.message || "Unknown error";
    console.error(
      LOG_PREFIX,
      `Global error: ${message}`,
      `at ${event.filename}:${event.lineno}:${event.colno}`,
      error?.stack || ""
    );
  });
}