History

Use tagged workspace read errors

Cursor Agent committed 4 months ago

Commit 7f891481 parent 05760162 files · +75 −8Browse files

Showing the changes to apps/server/src/workspace/WorkspaceFileSystem.ts (1 of 2 files). Show all

Unified · Split

apps/server/src/workspace/WorkspaceFileSystem.ts+62−4
@@ -24,6 +24,46 @@ import * as WorkspacePaths from "./WorkspacePaths.ts"; · 23 unmodified lines
2424
2525 const PROJECT_READ_FILE_MAX_BYTES = 1024 * 1024;
2626
27+class WorkspaceReadFileResolvedOutsideRootError extends Schema.TaggedErrorClass<WorkspaceReadFileResolvedOutsideRootError>()(
28+ "WorkspaceReadFileResolvedOutsideRootError",
29+ {
30+ cwd: Schema.String,
31+ relativePath: Schema.String,
32+ realWorkspaceRoot: Schema.String,
33+ realTargetPath: Schema.String,
34+ },
35+) {
36+ override get message(): string {
37+ return "Workspace file path resolves outside the project root.";
38+ }
39+}
40+
41+class WorkspaceReadFileNotFileError extends Schema.TaggedErrorClass<WorkspaceReadFileNotFileError>()(
42+ "WorkspaceReadFileNotFileError",
43+ {
44+ cwd: Schema.String,
45+ relativePath: Schema.String,
46+ fileType: Schema.String,
47+ },
48+) {
49+ override get message(): string {
50+ return "Workspace path is not a file.";
51+ }
52+}
53+
54+class WorkspaceReadFileBinaryFileError extends Schema.TaggedErrorClass<WorkspaceReadFileBinaryFileError>()(
55+ "WorkspaceReadFileBinaryFileError",
56+ {
57+ cwd: Schema.String,
58+ relativePath: Schema.String,
59+ nulByteOffset: Schema.Number,
60+ },
61+) {
62+ override get message(): string {
63+ return "Binary files cannot be previewed as text.";
64+ }
65+}
66+
2767 export class WorkspaceFileSystemError extends Schema.TaggedErrorClass<WorkspaceFileSystemError>()(
2868 "WorkspaceFileSystemError",
2969 {
@@ -96,22 +136,40 @@ export const make = Effect.gen(function* () { · 66 unmodified lines
96136 path.isAbsolute(relativeRealPath)
97137 ) {
98138 return yield* Effect.fail(
99− new Error("Workspace file path resolves outside the project root."),
139+ new WorkspaceReadFileResolvedOutsideRootError({
140+ cwd: input.cwd,
141+ relativePath: target.relativePath,
142+ realWorkspaceRoot,
143+ realTargetPath,
144+ }),
100145 );
101146 }
102147
103148 const handle = yield* fileSystem.open(realTargetPath, { flag: "r" });
104149 const stat = yield* handle.stat;
105150 if (stat.type !== "File") {
106− return yield* Effect.fail(new Error("Workspace path is not a file."));
151+ return yield* Effect.fail(
152+ new WorkspaceReadFileNotFileError({
153+ cwd: input.cwd,
154+ relativePath: target.relativePath,
155+ fileType: stat.type,
156+ }),
157+ );
107158 }
108159 const byteLength = Number(stat.size);
109160 const bytesToRead = Math.min(byteLength, PROJECT_READ_FILE_MAX_BYTES);
110161 const buffer = new Uint8Array(bytesToRead);
111162 const bytesRead = yield* handle.read(buffer);
112163 const fileBytes = buffer.subarray(0, Number(bytesRead));
113− if (fileBytes.includes(0)) {
114− return yield* Effect.fail(new Error("Binary files cannot be previewed as text."));
164+ const nulByteOffset = fileBytes.indexOf(0);
165+ if (nulByteOffset !== -1) {
166+ return yield* Effect.fail(
167+ new WorkspaceReadFileBinaryFileError({
168+ cwd: input.cwd,
169+ relativePath: target.relativePath,
170+ nulByteOffset,
171+ }),
172+ );
115173 }
116174 const contents = new TextDecoder("utf-8").decode(fileBytes);
117175 return {