diff --git a/packages/twenty-front/src/modules/apollo/hooks/useApolloFactory.ts b/packages/twenty-front/src/modules/apollo/hooks/useApolloFactory.ts index af41baff61..4b16d9e759 100644 --- a/packages/twenty-front/src/modules/apollo/hooks/useApolloFactory.ts +++ b/packages/twenty-front/src/modules/apollo/hooks/useApolloFactory.ts @@ -89,6 +89,14 @@ export const useApolloFactory = (options: Partial> = {}) => { }, }); }, + onPayloadTooLarge: (message) => { + enqueueErrorSnackBar({ + message, + options: { + dedupeKey: 'payload-too-large', + }, + }); + }, extraLinks: [], isDebugMode: process.env.IS_DEBUG_MODE === 'true', // Override options diff --git a/packages/twenty-front/src/modules/apollo/services/__tests__/apollo.factory.test.ts b/packages/twenty-front/src/modules/apollo/services/__tests__/apollo.factory.test.ts index ab15fdb2da..45d5c586b8 100644 --- a/packages/twenty-front/src/modules/apollo/services/__tests__/apollo.factory.test.ts +++ b/packages/twenty-front/src/modules/apollo/services/__tests__/apollo.factory.test.ts @@ -27,6 +27,7 @@ jest.mock('@/auth/services/AuthService', () => { const mockOnError = jest.fn(); const mockOnNetworkError = jest.fn(); +const mockOnPayloadTooLarge = jest.fn(); const mockWorkspaceMember = { id: 'workspace-member-id', @@ -81,6 +82,7 @@ const createMockOptions = (): Options => ({ isDebugMode: true, onError: mockOnError, onNetworkError: mockOnNetworkError, + onPayloadTooLarge: mockOnPayloadTooLarge, appVersion: '1.0.0', }); @@ -226,4 +228,21 @@ describe('ApolloFactory', () => { apolloFactory.updateWorkspaceMember(newWorkspaceMember); expect(apolloFactory['currentWorkspaceMember']).toEqual(newWorkspaceMember); }); + + it('should call onPayloadTooLarge when encountering a 413 error', async () => { + fetchMock.mockResponse(() => + Promise.reject({ + statusCode: 413, + message: 'Payload Too Large', + }), + ); + + try { + await makeRequest(); + } catch { + expect(mockOnPayloadTooLarge).toHaveBeenCalledWith( + expect.stringContaining('Uploaded content is too large'), + ); + } + }, 10000); }); diff --git a/packages/twenty-front/src/modules/apollo/services/apollo.factory.ts b/packages/twenty-front/src/modules/apollo/services/apollo.factory.ts index e12b3392d7..02b934c907 100644 --- a/packages/twenty-front/src/modules/apollo/services/apollo.factory.ts +++ b/packages/twenty-front/src/modules/apollo/services/apollo.factory.ts @@ -53,6 +53,7 @@ export interface Options extends ApolloClientOptions { onTokenPairChange?: (tokenPair: AuthTokenPair) => void; onUnauthenticatedError?: () => void; onAppVersionMismatch?: (message: string) => void; + onPayloadTooLarge?: (message: string) => void; currentWorkspaceMember: CurrentWorkspaceMember | null; currentWorkspace: CurrentWorkspace | null; extraLinks?: ApolloLink[]; @@ -74,6 +75,7 @@ export class ApolloFactory implements ApolloManager { onTokenPairChange, onUnauthenticatedError, onAppVersionMismatch, + onPayloadTooLarge, currentWorkspaceMember, currentWorkspace, extraLinks, @@ -142,6 +144,9 @@ export class ApolloFactory implements ApolloManager { if (this.isAuthenticationError(error)) { return false; } + if (this.isPayloadTooLargeError(error)) { + return false; + } return Boolean(error); }, }, @@ -296,6 +301,11 @@ export class ApolloFactory implements ApolloManager { return handleTokenRenewal(operation, forward); } + if (this.isPayloadTooLargeError(networkError as ServerError)) { + onPayloadTooLarge?.(t`Uploaded content is too large.`); + return; + } + if (isDebugMode === true) { logDebug(`[Network error]: ${networkError}`); } @@ -344,6 +354,10 @@ export class ApolloFactory implements ApolloManager { return error.statusCode === 401; } + private isPayloadTooLargeError(error: ServerError): boolean { + return error.statusCode === 413; + } + updateWorkspaceMember(workspaceMember: CurrentWorkspaceMember | null) { this.currentWorkspaceMember = workspaceMember; }