Files
twenty/packages/twenty-server/src/engine/subscriptions/event-stream.exception.ts
T
Thomas TrompetteandGitHub 95a34d8517 Return false instead of throwing when event stream does not exist (#20165)
## 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)
2026-05-04 15:06:18 +00:00

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),
});
}
}