## Summary - When an event stream expires (TTL), `addQueryToEventStream` and `removeQueryFromEventStream` now return `false` instead of throwing `EVENT_STREAM_DOES_NOT_EXIST` as an `InternalServerError` - Frontend checks the mutation return value and triggers the destroy/recreate cycle, same recovery behavior without the error path - Removes `EVENT_STREAM_DOES_NOT_EXIST` from exception code, exception filter, and frontend graceful error check since it's no longer thrown ## Test plan - [x] Verify that when an event stream TTL expires, the frontend silently recreates the stream without error noise in logs/Sentry - [x] Verify that `NOT_AUTHORIZED` errors still throw correctly on both mutations - [ ] Verify that the subscription `onEventSubscription` still works end-to-end with stream creation, query registration, and heartbeat TTL refresh Made with [Cursor](https://cursor.com)
37 lines
1.1 KiB
TypeScript
37 lines
1.1 KiB
TypeScript
import { type MessageDescriptor } from '@lingui/core';
|
|
import { msg } from '@lingui/core/macro';
|
|
import { assertUnreachable } from 'twenty-shared/utils';
|
|
|
|
import { CustomException } from 'src/utils/custom-exception';
|
|
|
|
export enum EventStreamExceptionCode {
|
|
EVENT_STREAM_ALREADY_EXISTS = 'EVENT_STREAM_ALREADY_EXISTS',
|
|
NOT_AUTHORIZED = 'NOT_AUTHORIZED',
|
|
}
|
|
|
|
const getEventStreamExceptionUserFriendlyMessage = (
|
|
code: EventStreamExceptionCode,
|
|
) => {
|
|
switch (code) {
|
|
case EventStreamExceptionCode.EVENT_STREAM_ALREADY_EXISTS:
|
|
return msg`Failed to receive real time updates.`;
|
|
case EventStreamExceptionCode.NOT_AUTHORIZED:
|
|
return msg`You are not authorized to perform this action.`;
|
|
default:
|
|
assertUnreachable(code);
|
|
}
|
|
};
|
|
|
|
export class EventStreamException extends CustomException<EventStreamExceptionCode> {
|
|
constructor(
|
|
message: string,
|
|
code: EventStreamExceptionCode,
|
|
{ userFriendlyMessage }: { userFriendlyMessage?: MessageDescriptor } = {},
|
|
) {
|
|
super(message, code, {
|
|
userFriendlyMessage:
|
|
userFriendlyMessage ?? getEventStreamExceptionUserFriendlyMessage(code),
|
|
});
|
|
}
|
|
}
|