diff --git a/components-ui/icon/wrapper.tsx b/components-ui/icon/wrapper.tsx index eae0a00a5..53047d785 100644 --- a/components-ui/icon/wrapper.tsx +++ b/components-ui/icon/wrapper.tsx @@ -23,7 +23,7 @@ export const Icon: React.FC> = ({ console.error(`Error in : ${slug} icon does not exists`); } return ( -
+ > = ({ {icon} {children} -
+ ); }; diff --git a/components-ui/information-tooltip/index.tsx b/components-ui/information-tooltip/index.tsx index 832a290f8..5c7b0e760 100644 --- a/components-ui/information-tooltip/index.tsx +++ b/components-ui/information-tooltip/index.tsx @@ -83,7 +83,7 @@ function InformationTooltip({ }} > {children} -
{label} -
+ ); diff --git a/components/espace-agent-components/documents/data-section/actes.tsx b/components/espace-agent-components/documents/data-section/actes.tsx index 14f694a23..48e725daf 100644 --- a/components/espace-agent-components/documents/data-section/actes.tsx +++ b/components/espace-agent-components/documents/data-section/actes.tsx @@ -89,7 +89,7 @@ function ActesTable({ actes }: IActesTableProps) { a.actes && ( ), diff --git a/components/table/copy-paste.tsx b/components/table/copy-paste.tsx index b0c6db042..bd4276947 100644 --- a/components/table/copy-paste.tsx +++ b/components/table/copy-paste.tsx @@ -31,9 +31,9 @@ export function CopyPaste({ ? children.replace(/\s/g, '') : children; - if (navigator.clipboard) { + try { navigator.clipboard.writeText(valueToCopy); - } else { + } catch { const el = document.createElement('textarea'); el.value = valueToCopy; document.body.appendChild(el); diff --git a/models/exceptions.ts b/models/exceptions.ts index f8d79ec92..357ce5981 100644 --- a/models/exceptions.ts +++ b/models/exceptions.ts @@ -33,7 +33,7 @@ export class Exception extends Error { public context: IExceptionContext; constructor({ name, message, cause, context }: IExceptionArgument) { if (message == undefined && cause && 'name' in cause) { - message = cause.name; + message = cause.name !== 'Error' ? cause.name : cause.message; } super(message, { cause }); this.name = name; diff --git a/sentry.client.config.ts b/sentry.client.config.ts index 26c16876a..cf103f823 100644 --- a/sentry.client.config.ts +++ b/sentry.client.config.ts @@ -8,6 +8,7 @@ declare global { IS_OUTDATED_BROWSER: boolean; } } + if (isNextJSSentryActivated) { Sentry.init({ dsn: process.env.NEXT_PUBLIC_SENTRY_DSN, @@ -37,6 +38,48 @@ if (isNextJSSentryActivated) { ]; } + if ( + hint.originalException && + typeof hint.originalException === 'object' && + 'message' in hint.originalException && + typeof hint.originalException.message === 'string' + ) { + /* + A LOT of hydration error happens in production. This can be due to a lot of reasons: + 1. Browser code in client SSRed component + 2. Bad nesting of HTML tags (e.g.

inside ) + 3. User browser extension messing with the DOM + + In any of these case, a unhandled exception is thrown and sentry catches it. + Only 1 and 2 are fixable. 3 is not. But real world data is not accurate enough to determine which is which. + + For now, we rely on E2E tests to catch those. + + In production, only the minified version of the error is sent to sentry. + These are the react error numbers that we want to ignore: + - [422](https://react.dev/errors/422) + - [423](https://react.dev/errors/423) + - [418](https://react.dev/errors/418) + - [425](https://react.dev/errors/425) + */ + if ( + hint.originalException.message.match( + /Minified React error #(422|423|418|425)/ + ) + ) { + event.fingerprint = ['React hydration error']; + } + + /* + This is a common error that happens when a chunk fails to load. We want to group them together. + */ + if ( + hint.originalException.message.match(/Loading chunk [\d]+ failed/) + ) { + event.fingerprint = ['Chunk load error']; + } + } + if (!event.tags) { event.tags = {}; }