fix(opencode): map filesystem client errors

This commit is contained in:
Kit Langton 2026-06-21 13:16:32 -04:00
parent 868c1fc596
commit f7b2843679
2 changed files with 18 additions and 4 deletions

View file

@ -1,10 +1,11 @@
import { EOL } from "os"
import { Effect } from "effect"
import { FileSystem } from "@opencode-ai/core/filesystem"
import { FSUtil } from "@opencode-ai/core/fs-util"
import { LocationServiceMap } from "@opencode-ai/core/location-layer"
import { Location } from "@opencode-ai/core/location"
import { AbsolutePath, RelativePath } from "@opencode-ai/core/schema"
import { effectCmd } from "../../effect-cmd"
import { CliError, effectCmd } from "../../effect-cmd"
import { cmd } from "../cmd"
const filesystem = <A, E, R>(effect: Effect.Effect<A, E, R>) =>
@ -13,6 +14,8 @@ const filesystem = <A, E, R>(effect: Effect.Effect<A, E, R>) =>
Effect.provide(LocationServiceMap.layer),
)
const fileError = (error: FileSystem.PathError | FSUtil.Error) => new CliError({ message: error.message })
const FileSearchCommand = effectCmd({
command: "search <query>",
describe: "search files by query",
@ -38,7 +41,9 @@ const FileReadCommand = effectCmd({
description: "File path to read",
}),
handler: Effect.fn("Cli.debug.file.read")(function* (args) {
const file = yield* filesystem(FileSystem.Service.use((svc) => svc.read({ path: RelativePath.make(args.path) })))
const file = yield* filesystem(
FileSystem.Service.use((svc) => svc.read({ path: RelativePath.make(args.path) })),
).pipe(Effect.mapError(fileError))
process.stdout.write(
JSON.stringify(
{ content: Buffer.from(file.content).toString("base64"), encoding: "base64", mime: file.mime },
@ -59,7 +64,9 @@ const FileListCommand = effectCmd({
description: "File path to list",
}),
handler: Effect.fn("Cli.debug.file.list")(function* (args) {
const files = yield* filesystem(FileSystem.Service.use((svc) => svc.list({ path: RelativePath.make(args.path) })))
const files = yield* filesystem(
FileSystem.Service.use((svc) => svc.list({ path: RelativePath.make(args.path) })),
).pipe(Effect.mapError(fileError))
process.stdout.write(JSON.stringify(files, null, 2) + EOL)
}),
})

View file

@ -10,6 +10,10 @@ import ignore from "ignore"
import path from "path"
import { HttpApiBuilder } from "effect/unstable/httpapi"
import { InstanceHttpApi } from "../api"
import { InvalidRequestError } from "../errors"
const invalidRequest = (error: FileSystem.PathError | FSUtil.Error) =>
new InvalidRequestError({ message: error.message, kind: error._tag })
export const fileHandlers = HttpApiBuilder.group(InstanceHttpApi, "file", (handlers) =>
Effect.gen(function* () {
@ -79,7 +83,9 @@ export const fileHandlers = HttpApiBuilder.group(InstanceHttpApi, "file", (handl
.readFileString(path.join(location.project.directory, ".ignore"))
.pipe(Effect.catch(() => Effect.succeed("")))
if (ignorefile) ignored.add(ignorefile)
return (yield* fs.list({ path: RelativePath.make(ctx.query.path) })).map((item) => ({
return (yield* fs
.list({ path: RelativePath.make(ctx.query.path) })
.pipe(Effect.mapError(invalidRequest))).map((item) => ({
name: path.basename(item.path),
path: item.path,
absolute: path.resolve(location.directory, item.path),
@ -101,6 +107,7 @@ export const fileHandlers = HttpApiBuilder.group(InstanceHttpApi, "file", (handl
return yield* filesystem(
FileSystem.Service.use((fs) => fs.read({ path: RelativePath.make(ctx.query.path) })),
).pipe(
Effect.mapError(invalidRequest),
Effect.flatMap((item) =>
Effect.gen(function* () {
const text = item.content.includes(0)