Files
oh-my-opencode/src/shared/tolerant-fsync.ts
T
YeonGyu-Kim 9d83255426 feat(shared): add tolerant-fsync utility for synced-folder filesystems
Adds isToleratedFsyncError, tolerantFsync (async, FileHandle), and
tolerantFsyncSync (sync, fd) helpers that swallow filesystem-limitation
errors during fsync (EPERM, EACCES, ENOTSUP, EINVAL) while still
propagating real errors (EIO, ENOSPC, EBADF, etc.). Synced folders
like iCloud Drive, OneDrive, and antivirus-locked files reject fsync
with EPERM even though the underlying write+rename succeeded; for the
runtime data this codebase persists, losing the durability hint is
acceptable in exchange for not blocking the operation entirely.

The helper is intentionally not barrel-exported (consumers import the
file directly), matching the existing convention for write-file-atomically.
2026-05-08 14:09:16 +09:00

53 lines
1.4 KiB
TypeScript

import { fsyncSync } from "node:fs"
import type { FileHandle } from "node:fs/promises"
import { log } from "./logger"
const TOLERATED_FSYNC_CODES: ReadonlySet<string> = new Set([
"EPERM",
"EACCES",
"ENOTSUP",
"EINVAL",
])
export function isToleratedFsyncError(error: unknown): boolean {
if (!(error instanceof Error)) return false
const code = (error as NodeJS.ErrnoException).code
return code !== undefined && TOLERATED_FSYNC_CODES.has(code)
}
export async function tolerantFsync(
fileHandle: FileHandle,
contextLabel: string,
): Promise<void> {
try {
await fileHandle.sync()
} catch (error) {
if (!isToleratedFsyncError(error)) throw error
log("fsync skipped due to filesystem limitation", {
event: "fsync-skipped",
contextLabel,
code: (error as NodeJS.ErrnoException).code,
message: error instanceof Error ? error.message : String(error),
})
}
}
export function tolerantFsyncSync(
fileDescriptor: number,
contextLabel: string,
fsyncImpl: typeof fsyncSync = fsyncSync,
): void {
try {
fsyncImpl(fileDescriptor)
} catch (error) {
if (!isToleratedFsyncError(error)) throw error
log("fsync skipped due to filesystem limitation", {
event: "fsync-skipped",
contextLabel,
code: (error as NodeJS.ErrnoException).code,
message: error instanceof Error ? error.message : String(error),
})
}
}