mirror of
https://github.com/toeverything/AFFiNE.git
synced 2026-02-13 21:05:19 +00:00
**Summary:** This PR improves the user feedback when encountering an HTTP 413 (_CONTENT_TOO_LARGE)_ error caused by a file size limit in the proxy / ingress controller in a self-hosted environment. **Example scenario:** A self-hosted environment serves AFFiNE through an nginx proxy, and the `client_max_body_size` variable in the configuration file is set to a smaller size (e.g. 1MB) than AFFiNE's own file size limit (typically 100MB). Previously, the user would get an error saying the file is larger than 100MB regardless of file size, as all of these cases resulted in the same internal error. With this fix, the _CONTENT_TOO_LARGE_ error is now handled separately and gives better feedback to the user that the failing upload is caused by a fault in the proxy configuration. **Screenshot of new error message** <img width="798" height="171" alt="1MB_now" src="https://github.com/user-attachments/assets/07b00cd3-ce37-4049-8674-2f3dcb916ab5" /> **Affected files:** 1. packages/common/nbstore/src/storage/errors/over-size.ts 2. packages/common/nbstore/src/impls/cloud/blob.ts I'm open to any suggestions in terms of the wording used in the message to the user. The fix has been tested with an nginx proxy. <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit * **Bug Fixes** * Improved user-facing error messages for file upload failures. When an upload exceeds the file size limit, users now receive a clearer message indicating that the upload was stopped by the network proxy due to the size restriction, providing better understanding of why the upload was rejected. <sub>✏️ Tip: You can customize this high-level summary in your review settings.</sub> <!-- end of auto-generated comment: release notes by coderabbit.ai -->
Space Storage
Usage
Independent Storage usage
import type { ConnectionStatus } from '@affine/nbstore';
import { IndexedDBDocStorage } from '@affine/nbstore/idb';
const storage = new IndexedDBDocStorage({
peer: 'local'
spaceId: 'my-new-workspace',
});
await storage.connect();
storage.connection.onStatusChange((status: ConnectionStatus, error?: Error) => {
ui.show(status, error);
});
// { docId: string, bin: Uint8Array, timestamp: Date, editor?: string } | null
const doc = await storage.getDoc('my-first-doc');
Use All storages together
import { SpaceStorage } from '@affine/nbstore';
import type { ConnectionStatus } from '@affine/nbstore';
import { IndexedDBDocStorage } from '@affine/nbstore/idb';
import { SqliteBlobStorage } from '@affine/nbstore/sqlite';
const storage = new SpaceStorage([new IndexedDBDocStorage({}), new SqliteBlobStorage({})]);
await storage.connect();
storage.on('connection', ({ storage, status, error }) => {
ui.show(storage, status, error);
});
await storage.get('doc').pushDocUpdate({ docId: 'my-first-doc', bin: new Uint8Array(), editor: 'me' });
await storage.tryGet('blob')?.get('img');
Put Storage behind Worker
import { SpaceStorageWorkerClient } from '@affine/nbstore/op';
import type { ConnectionStatus } from '@affine/nbstore';
import { IndexedDBDocStorage } from '@affine/nbstore/idb';
const client = new SpaceStorageWorkerClient();
client.addStorage(IndexedDBDocStorage, {
// options can only be structure-cloneable type
peer: 'local',
spaceType: 'workspace',
spaceId: 'my-new-workspace',
});
await client.connect();
client.ob$('connection', ({ storage, status, error }) => {
ui.show(storage, status, error);
});
await client.call('pushDocUpdate', { docId: 'my-first-doc', bin: new Uint8Array(), editor: 'me' });
// call unregistered op will leads to Error
// Error { message: 'Handler for operation [listHistory] is not registered.' }
await client.call('listHistories', { docId: 'my-first-doc' });