Skip to content

Commit fa5adbf

Browse files
committed
feat(fs): add better errors
1 parent 7a87970 commit fa5adbf

File tree

1 file changed

+180
-44
lines changed

1 file changed

+180
-44
lines changed

packages/fs/src/file.lib.ts

Lines changed: 180 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -596,7 +596,13 @@ class FsFileRead<
596596
* ```
597597
*/
598598
public async text() {
599-
return fs.readFile(this._path, this._encoding);
599+
try {
600+
return await fs.readFile(this._path, this._encoding);
601+
} catch (error) {
602+
throw new Error(`Failed to read text from ${this._path}`, {
603+
cause: error,
604+
});
605+
}
600606
}
601607

602608
/**
@@ -612,7 +618,13 @@ class FsFileRead<
612618
* ```
613619
*/
614620
public textSync() {
615-
return fsSync.readFileSync(this._path, this._encoding);
621+
try {
622+
return fsSync.readFileSync(this._path, this._encoding);
623+
} catch (error) {
624+
throw new Error(`Failed to read text from ${this._path}`, {
625+
cause: error,
626+
});
627+
}
616628
}
617629

618630
/**
@@ -675,9 +687,13 @@ class FsFileRead<
675687
public json<
676688
OUT = SCHEMA extends ZodSchema<infer O> ? O : unknown,
677689
>(): Promise<OUT> {
678-
return this.text().then((t) =>
679-
json.deserialize(t, { schema: this._schema }),
680-
);
690+
return this.text()
691+
.then((t) => json.deserialize(t, { schema: this._schema }))
692+
.catch((error) => {
693+
throw new Error(`Failed to read JSON from ${this._path}`, {
694+
cause: error,
695+
});
696+
});
681697
}
682698

683699
/**
@@ -699,9 +715,15 @@ class FsFileRead<
699715
public jsonSync<
700716
OUT = SCHEMA extends ZodSchema<infer O> ? O : unknown,
701717
>(): OUT {
702-
return json.deserialize(this.textSync(), {
703-
schema: this._schema,
704-
});
718+
try {
719+
return json.deserialize(this.textSync(), {
720+
schema: this._schema,
721+
});
722+
} catch (error) {
723+
throw new Error(`Failed to read JSON from ${this._path}`, {
724+
cause: error,
725+
});
726+
}
705727
}
706728

707729
/**
@@ -728,9 +750,13 @@ class FsFileRead<
728750
public yaml<
729751
OUT = SCHEMA extends ZodSchema<infer O> ? O : unknown,
730752
>(): Promise<OUT> {
731-
return this.text().then((t) =>
732-
yaml.deserialize(t, { schema: this._schema }),
733-
);
753+
return this.text()
754+
.then((t) => yaml.deserialize(t, { schema: this._schema }))
755+
.catch((error) => {
756+
throw new Error(`Failed to read YAML from ${this._path}`, {
757+
cause: error,
758+
});
759+
});
734760
}
735761

736762
/**
@@ -753,9 +779,15 @@ class FsFileRead<
753779
public yamlSync<
754780
OUT = SCHEMA extends ZodSchema<infer O> ? O : unknown,
755781
>(): OUT {
756-
return yaml.deserialize(this.textSync(), {
757-
schema: this._schema,
758-
});
782+
try {
783+
return yaml.deserialize(this.textSync(), {
784+
schema: this._schema,
785+
});
786+
} catch (error) {
787+
throw new Error(`Failed to read YAML from ${this._path}`, {
788+
cause: error,
789+
});
790+
}
759791
}
760792

761793
/**
@@ -785,7 +817,13 @@ class FsFileRead<
785817
* - Does not support all XML features (see documentation for details)
786818
*/
787819
public async xml<T extends Array<Xml.Node>>(): Promise<T> {
788-
return this.text().then((content) => xml.parse<T>(content));
820+
return this.text()
821+
.then((content) => xml.parse<T>(content))
822+
.catch((error) => {
823+
throw new Error(`Failed to read XML from ${this._path}`, {
824+
cause: error,
825+
});
826+
});
789827
}
790828

791829
/**
@@ -810,7 +848,13 @@ class FsFileRead<
810848
* - Does not support all XML features (see documentation for details)
811849
*/
812850
public xmlSync<T extends Array<Xml.Node>>(): T {
813-
return xml.parse<T>(this.textSync());
851+
try {
852+
return xml.parse<T>(this.textSync());
853+
} catch (error) {
854+
throw new Error(`Failed to read XML from ${this._path}`, {
855+
cause: error,
856+
});
857+
}
814858
}
815859

816860
/**
@@ -830,7 +874,13 @@ class FsFileRead<
830874
* ```
831875
*/
832876
public async base64(): Promise<string> {
833-
return fs.readFile(this._path, "base64");
877+
try {
878+
return await fs.readFile(this._path, "base64");
879+
} catch (error) {
880+
throw new Error(`Failed to read base64 from ${this._path}`, {
881+
cause: error,
882+
});
883+
}
834884
}
835885

836886
/**
@@ -847,7 +897,13 @@ class FsFileRead<
847897
* ```
848898
*/
849899
public base64Sync(): string {
850-
return fsSync.readFileSync(this._path, "base64");
900+
try {
901+
return fsSync.readFileSync(this._path, "base64");
902+
} catch (error) {
903+
throw new Error(`Failed to read base64 from ${this._path}`, {
904+
cause: error,
905+
});
906+
}
851907
}
852908

853909
/**
@@ -921,11 +977,17 @@ class FsFileRead<
921977
* @throws If schema validation fails when a schema is provided
922978
*/
923979
public md<DATA_SHAPE = SCHEMA extends ZodSchema<infer O> ? O : unknown>() {
924-
return this.text().then((t) =>
925-
MdDoc.withOptions<DATA_SHAPE>({
926-
schema: this._schema,
927-
}).fromString(t),
928-
);
980+
return this.text()
981+
.then((t) =>
982+
MdDoc.withOptions<DATA_SHAPE>({
983+
schema: this._schema,
984+
}).fromString(t),
985+
)
986+
.catch((error) => {
987+
throw new Error(`Failed to read markdown from ${this._path}`, {
988+
cause: error,
989+
});
990+
});
929991
}
930992

931993
/**
@@ -940,9 +1002,15 @@ class FsFileRead<
9401002
public mdSync<
9411003
DATA_SHAPE = SCHEMA extends ZodSchema<infer O> ? O : unknown,
9421004
>() {
943-
return MdDoc.withOptions<DATA_SHAPE>({
944-
schema: this._schema,
945-
}).fromString(this.textSync());
1005+
try {
1006+
return MdDoc.withOptions<DATA_SHAPE>({
1007+
schema: this._schema,
1008+
}).fromString(this.textSync());
1009+
} catch (error) {
1010+
throw new Error(`Failed to read markdown from ${this._path}`, {
1011+
cause: error,
1012+
});
1013+
}
9461014
}
9471015
}
9481016

@@ -990,8 +1058,14 @@ class FsFileWrite<
9901058
if (this._mode === "preserve" && (await FsFile.from(this._path).exists()))
9911059
return;
9921060
const dirname = path.dirname(this._path);
993-
await fs.mkdir(dirname, { recursive: true });
994-
await fs.writeFile(this._path, content.toString(), this._encoding);
1061+
try {
1062+
await fs.mkdir(dirname, { recursive: true });
1063+
await fs.writeFile(this._path, content.toString(), this._encoding);
1064+
} catch (error) {
1065+
throw new Error(`Failed to write text to ${this._path}`, {
1066+
cause: error,
1067+
});
1068+
}
9951069
}
9961070

9971071
/**
@@ -1007,8 +1081,14 @@ class FsFileWrite<
10071081
if (this._mode === "preserve" && FsFile.from(this._path).existsSync())
10081082
return;
10091083
const dirname = path.dirname(this._path);
1010-
fsSync.mkdirSync(dirname, { recursive: true });
1011-
fsSync.writeFileSync(this._path, content.toString(), this._encoding);
1084+
try {
1085+
fsSync.mkdirSync(dirname, { recursive: true });
1086+
fsSync.writeFileSync(this._path, content.toString(), this._encoding);
1087+
} catch (error) {
1088+
throw new Error(`Failed to write text to ${this._path}`, {
1089+
cause: error,
1090+
});
1091+
}
10121092
}
10131093

10141094
/**
@@ -1024,7 +1104,13 @@ class FsFileWrite<
10241104
public async json<T>(
10251105
data: TSchema extends ZodSchema<any, infer I> ? I : T,
10261106
): Promise<void> {
1027-
return this.text(json.serialize(data, { schema: this._schema }));
1107+
return this.text(json.serialize(data, { schema: this._schema })).catch(
1108+
(error) => {
1109+
throw new Error(`Failed to write JSON to ${this._path}`, {
1110+
cause: error,
1111+
});
1112+
},
1113+
);
10281114
}
10291115

10301116
// Todo: add mergeJson
@@ -1044,7 +1130,11 @@ class FsFileWrite<
10441130
): Promise<void> {
10451131
return this.text(
10461132
json.serialize(data, { schema: this._schema, pretty: true }) + "\n",
1047-
);
1133+
).catch((error) => {
1134+
throw new Error(`Failed to write pretty JSON to ${this._path}`, {
1135+
cause: error,
1136+
});
1137+
});
10481138
}
10491139

10501140
/**
@@ -1060,7 +1150,13 @@ class FsFileWrite<
10601150
public jsonSync<T>(
10611151
data: TSchema extends ZodSchema<any, infer I> ? I : T,
10621152
): void {
1063-
return this.textSync(json.serialize(data, { schema: this._schema }));
1153+
try {
1154+
return this.textSync(json.serialize(data, { schema: this._schema }));
1155+
} catch (error) {
1156+
throw new Error(`Failed to write JSON to ${this._path}`, {
1157+
cause: error,
1158+
});
1159+
}
10641160
}
10651161

10661162
/**
@@ -1076,9 +1172,15 @@ class FsFileWrite<
10761172
public prettyJsonSync<T = unknown>(
10771173
data: TSchema extends ZodSchema<any, infer I> ? I : T,
10781174
): void {
1079-
return this.textSync(
1080-
json.serialize(data, { schema: this._schema, pretty: true }) + "\n",
1081-
);
1175+
try {
1176+
return this.textSync(
1177+
json.serialize(data, { schema: this._schema, pretty: true }) + "\n",
1178+
);
1179+
} catch (error) {
1180+
throw new Error(`Failed to write pretty JSON to ${this._path}`, {
1181+
cause: error,
1182+
});
1183+
}
10821184
}
10831185

10841186
/**
@@ -1093,7 +1195,13 @@ class FsFileWrite<
10931195
public async yaml<T = unknown>(
10941196
data: TSchema extends ZodSchema<any, infer I> ? I : T,
10951197
): Promise<void> {
1096-
return this.text(yaml.serialize(data, { schema: this._schema }));
1198+
return this.text(yaml.serialize(data, { schema: this._schema })).catch(
1199+
(error) => {
1200+
throw new Error(`Failed to write YAML to ${this._path}`, {
1201+
cause: error,
1202+
});
1203+
},
1204+
);
10971205
}
10981206

10991207
/**
@@ -1109,7 +1217,13 @@ class FsFileWrite<
11091217
public yamlSync<T = unknown>(
11101218
data: TSchema extends ZodSchema<any, infer I> ? I : T,
11111219
): void {
1112-
return this.textSync(yaml.serialize(data, { schema: this._schema }));
1220+
try {
1221+
return this.textSync(yaml.serialize(data, { schema: this._schema }));
1222+
} catch (error) {
1223+
throw new Error(`Failed to write YAML to ${this._path}`, {
1224+
cause: error,
1225+
});
1226+
}
11131227
}
11141228

11151229
/**
@@ -1124,8 +1238,14 @@ class FsFileWrite<
11241238
if (this._mode === "preserve" && (await FsFile.from(this._path).exists()))
11251239
return;
11261240
const dirname = path.dirname(this._path);
1127-
await fs.mkdir(dirname, { recursive: true });
1128-
await fs.writeFile(this._path, data.toString(), "base64");
1241+
try {
1242+
await fs.mkdir(dirname, { recursive: true });
1243+
await fs.writeFile(this._path, data.toString(), "base64");
1244+
} catch (error) {
1245+
throw new Error(`Failed to write base64 to ${this._path}`, {
1246+
cause: error,
1247+
});
1248+
}
11291249
}
11301250

11311251
/**
@@ -1141,8 +1261,14 @@ class FsFileWrite<
11411261
if (this._mode === "preserve" && FsFile.from(this._path).existsSync())
11421262
return;
11431263
const dirname = path.dirname(this._path);
1144-
fsSync.mkdirSync(dirname, { recursive: true });
1145-
return fsSync.writeFileSync(this._path, data.toString(), "base64");
1264+
try {
1265+
fsSync.mkdirSync(dirname, { recursive: true });
1266+
fsSync.writeFileSync(this._path, data.toString(), "base64");
1267+
} catch (error) {
1268+
throw new Error(`Failed to write base64 to ${this._path}`, {
1269+
cause: error,
1270+
});
1271+
}
11461272
}
11471273

11481274
/**
@@ -1154,7 +1280,11 @@ class FsFileWrite<
11541280
* @throws If schema validation fails or if the write operation fails
11551281
*/
11561282
public md(data: MdDoc) {
1157-
return this.text(data.toMd());
1283+
return this.text(data.toMd()).catch((error) => {
1284+
throw new Error(`Failed to write markdown to ${this._path}`, {
1285+
cause: error,
1286+
});
1287+
});
11581288
}
11591289

11601290
/**
@@ -1167,7 +1297,13 @@ class FsFileWrite<
11671297
* @synchronous
11681298
*/
11691299
public mdSync(data: MdDoc) {
1170-
return this.textSync(data.toMd());
1300+
try {
1301+
return this.textSync(data.toMd());
1302+
} catch (error) {
1303+
throw new Error(`Failed to write markdown to ${this._path}`, {
1304+
cause: error,
1305+
});
1306+
}
11711307
}
11721308
}
11731309

0 commit comments

Comments
 (0)