mirror of
https://github.com/bulwarkmail/webmail.git
synced 2026-11-13 08:17:50 +00:00
93 lines
2.6 KiB
TypeScript
93 lines
2.6 KiB
TypeScript
/**
|
|
* What went wrong, in the words the settings page shows: keys under `files_sync.errors.`
|
|
* (the ui writes the strings). Errors are told apart by name, not instanceof: Next has more
|
|
* than one copy of a module.
|
|
*/
|
|
|
|
import type { FilesError } from '@/lib/desktop/types';
|
|
|
|
export type FilesSyncErrorName =
|
|
| 'offline'
|
|
| 'server_refused'
|
|
| 'too_large'
|
|
| 'name_invalid'
|
|
| 'disk_full'
|
|
| 'denied'
|
|
| 'busy'
|
|
| 'quota'
|
|
| 'not_found'
|
|
| 'policy'
|
|
| 'failed';
|
|
|
|
/** The key in the `files_sync` namespace. */
|
|
export function errorKey(name: FilesSyncErrorName): string {
|
|
return `errors.${name}`;
|
|
}
|
|
|
|
/** A disk answer the engine can't go on from for this item. */
|
|
export class LocalError extends Error {
|
|
constructor(readonly error: FilesError) {
|
|
super(`files:${error}`);
|
|
this.name = 'LocalError';
|
|
}
|
|
}
|
|
|
|
export function localErrorName(error: FilesError): FilesSyncErrorName {
|
|
switch (error) {
|
|
case 'full':
|
|
return 'disk_full';
|
|
case 'denied':
|
|
case 'outside':
|
|
case 'gesture':
|
|
return 'denied';
|
|
case 'busy':
|
|
return 'busy';
|
|
case 'name':
|
|
return 'name_invalid';
|
|
case 'policy':
|
|
return 'policy';
|
|
case 'missing':
|
|
return 'not_found';
|
|
default:
|
|
return 'failed';
|
|
}
|
|
}
|
|
|
|
/** The server can't be reached, or is too busy now: the work waits, nothing failed. */
|
|
export function isOffline(error: unknown): boolean {
|
|
const e = error as { name?: string; kind?: string; status?: number } | null;
|
|
if (e?.name !== 'TransportError') return false;
|
|
if (e.kind === 'network' || e.kind === 'rate') return true;
|
|
return e.kind === 'http' && typeof e.status === 'number' && e.status >= 500;
|
|
}
|
|
|
|
/** The server no longer takes this login. */
|
|
export function isAuthRefused(error: unknown): boolean {
|
|
const e = error as { name?: string; kind?: string } | null;
|
|
return e?.name === 'TransportError' && e.kind === 'auth';
|
|
}
|
|
|
|
/** What a server error on one item means. */
|
|
export function remoteErrorName(error: unknown): FilesSyncErrorName {
|
|
const e = error as { name?: string; type?: string; status?: number } | null;
|
|
if (isOffline(error)) return 'offline';
|
|
if (isAuthRefused(error)) return 'server_refused';
|
|
if (e?.name === 'TransportError' && e.status === 413) return 'too_large';
|
|
switch (e?.type) {
|
|
case 'overQuota':
|
|
return 'quota';
|
|
case 'forbidden':
|
|
case 'accountReadOnly':
|
|
return 'denied';
|
|
case 'notFound':
|
|
return 'not_found';
|
|
case 'tooLarge':
|
|
return 'too_large';
|
|
case 'invalidProperties':
|
|
case 'alreadyExists':
|
|
return 'name_invalid';
|
|
default:
|
|
return 'failed';
|
|
}
|
|
}
|