diff --git a/__test__/components/EventErrorHandling.test.tsx b/__test__/components/EventErrorHandling.test.tsx
new file mode 100644
index 0000000..f08e8d1
--- /dev/null
+++ b/__test__/components/EventErrorHandling.test.tsx
@@ -0,0 +1,96 @@
+import { act, fireEvent, screen, waitFor } from "@testing-library/react";
+import { renderWithProviders } from "../utils/Renderwithproviders";
+import CalendarLayout from "../../src/components/Calendar/CalendarLayout";
+
+describe("Event Error Handling", () => {
+ beforeEach(() => {
+ localStorage.clear();
+ jest.clearAllMocks();
+ });
+
+ const today = new Date();
+ const start = new Date(today);
+ start.setHours(10, 0, 0, 0);
+ const end = new Date(today);
+ end.setHours(11, 0, 0, 0);
+
+ const erroredState = {
+ user: {
+ userData: {
+ sub: "test",
+ email: "test@test.com",
+ sid: "mockSid",
+ openpaasId: "user1",
+ },
+ tokens: { accessToken: "token" },
+ },
+ calendars: {
+ list: {
+ "user1/cal1": {
+ name: "Calendar personal",
+ id: "user1/cal1",
+ color: { light: "#FF0000", dark: "#000" },
+ ownerEmails: ["alice@example.com"],
+ events: {
+ event1: {
+ id: "event1",
+ calId: "user1/cal1",
+ uid: "event1",
+ title: "Test Event",
+ start: start.toISOString(),
+ end: start.toISOString(),
+ partstat: "ACCEPTED",
+ organizer: {
+ cn: "Alice",
+ cal_address: "alice@example.com",
+ },
+ attendee: [
+ {
+ cn: "Alice",
+ partstat: "ACCEPTED",
+ rsvp: "TRUE",
+ role: "REQ-PARTICIPANT",
+ cutype: "INDIVIDUAL",
+ cal_address: "alice@example.com",
+ },
+ ],
+ },
+ },
+ },
+ },
+ pending: false,
+ },
+ };
+
+ it("BUGFIX: does not re-report errors after clearing error snackbar", async () => {
+ const consoleWarnSpy = jest.spyOn(console, "warn").mockImplementation();
+
+ await act(async () =>
+ renderWithProviders(, erroredState)
+ );
+
+ await waitFor(() => {
+ expect(screen.getByText("Test Event"));
+ expect(screen.getByRole("alert")).toBeInTheDocument();
+ });
+ const closeButton = screen.queryByRole("button", { name: "common.ok" });
+
+ if (closeButton) {
+ const initialWarnCount = consoleWarnSpy.mock.calls.length;
+
+ await act(async () => {
+ fireEvent.click(closeButton);
+ });
+
+ await waitFor(() => {
+ expect(screen.queryByRole("alert")).not.toBeInTheDocument();
+ });
+
+ const afterCloseWarnCount = consoleWarnSpy.mock.calls.length;
+
+ expect(afterCloseWarnCount).toBe(initialWarnCount);
+ }
+
+ consoleWarnSpy.mockRestore();
+ });
+});
diff --git a/src/components/Error/EventErrorHandler.ts b/src/components/Error/EventErrorHandler.ts
index f2f2082..fd47839 100644
--- a/src/components/Error/EventErrorHandler.ts
+++ b/src/components/Error/EventErrorHandler.ts
@@ -1,5 +1,6 @@
export class EventErrorHandler {
private errors = new Map();
+ private reportedEvents = new Set();
private onErrorCallback?: (messages: string[]) => void;
setErrorCallback(callback: (messages: string[]) => void) {
@@ -7,7 +8,8 @@ export class EventErrorHandler {
}
reportError(eventId: string, message: string) {
- if (!this.errors.has(eventId)) {
+ if (!this.reportedEvents.has(eventId)) {
+ this.reportedEvents.add(eventId);
this.errors.set(eventId, message);
console.warn(`[EventErrorHandler] ${eventId}: ${message}`);
this.emit();
diff --git a/src/components/Event/EventChip/ErrorEventChip.tsx b/src/components/Event/EventChip/ErrorEventChip.tsx
index 58219f7..144ea0a 100644
--- a/src/components/Event/EventChip/ErrorEventChip.tsx
+++ b/src/components/Event/EventChip/ErrorEventChip.tsx
@@ -1,5 +1,5 @@
-import React from "react";
import { Card, Typography } from "@mui/material";
+import { useRef, useEffect } from "react";
import { EventErrorHandler } from "../../Error/EventErrorHandler";
export function ErrorEventChip({
@@ -11,9 +11,21 @@ export function ErrorEventChip({
errorHandler: EventErrorHandler;
error: any;
}) {
- const message =
- error instanceof Error ? error.message : "Unknown error during rendering";
- errorHandler.reportError(event._def.extendedProps.uid || event.id, message);
+ const hasReported = useRef(false);
+
+ useEffect(() => {
+ if (!hasReported.current) {
+ const message =
+ error instanceof Error
+ ? error.message
+ : `${error.class} error during rendering ${event._def.extendedProps.uid || event.id}`;
+ errorHandler.reportError(
+ event._def.extendedProps.uid || event.id,
+ message
+ );
+ hasReported.current = true;
+ }
+ }, [event, errorHandler, error]);
return (