Skip to content

Commit 67e5baf

Browse files
ENGG-3151: Track and handle file errors in local sync (#138)
1 parent 5fcecee commit 67e5baf

File tree

8 files changed

+430
-89
lines changed

8 files changed

+430
-89
lines changed

src/renderer/actions/local-sync/common-utils.ts

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -74,22 +74,22 @@ export function createFsResource<T extends FsResource["type"]>(params: {
7474
}
7575
}
7676

77-
export function parseRawJson<T extends TSchema>(
78-
json: Record<any, any>,
77+
export function parseRaw<T extends TSchema>(
78+
content: any,
7979
validator: T
8080
): ContentParseResult<Static<T>> {
8181
try {
8282
const parsedContent = Value.Parse(
8383
["Assert"],
8484
validator,
85-
json
85+
content
8686
) as Static<T>;
8787
return {
8888
type: "success",
8989
content: parsedContent,
9090
} as ContentParseResult<Static<T>>; // Casting because TS was not able to infer from fn result type
9191
} catch {
92-
const error = [...Value.Errors(validator, json)][0];
92+
const error = [...Value.Errors(validator, content)][0];
9393
return {
9494
type: "error",
9595
error: {
@@ -99,13 +99,13 @@ export function parseRawJson<T extends TSchema>(
9999
}
100100
}
101101

102-
export function parseContent<T extends TSchema>(
102+
export function parseJsonContent<T extends TSchema>(
103103
content: string,
104104
validator: T
105105
): ContentParseResult<Static<T>> {
106106
try {
107107
const parsedJson = JSON.parse(content);
108-
return parseRawJson(parsedJson, validator);
108+
return parseRaw(parsedJson, validator);
109109
} catch (e: any) {
110110
return {
111111
type: "error",
@@ -123,6 +123,7 @@ export function getIdFromPath(path: string) {
123123
export function mapSuccessWrite<
124124
T extends FileSystemResult<{ resource: FsResource }>,
125125
R extends FileSystemResult<any>
126+
// eslint-disable-next-line no-unused-vars
126127
>(writeResult: T, fn: (id: string) => R) {
127128
if (writeResult.type === "success") {
128129
const { resource } = writeResult.content;
@@ -140,6 +141,7 @@ export function mapSuccessfulFsResult<
140141
Content,
141142
T extends FileSystemResult<Content>,
142143
R
144+
// eslint-disable-next-line no-unused-vars
143145
>(result: T, fn: (param: T & { type: "success" }) => R) {
144146
if (result.type === "success") {
145147
const newContent = fn(result as T & { type: "success" });
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
import { Static, TSchema } from "@sinclair/typebox";
2+
import { ContentParseResult, FileTypeEnum } from "../types";
3+
4+
export abstract class FileType<V extends TSchema> {
5+
abstract type: FileTypeEnum;
6+
7+
abstract validator: V;
8+
9+
// eslint-disable-next-line no-unused-vars
10+
abstract parse(content: any): ContentParseResult<Static<V>>;
11+
}
Lines changed: 109 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,109 @@
1+
/* eslint-disable max-classes-per-file */
2+
3+
import { FileType } from "./file-type.interface";
4+
import {
5+
ApiRecord,
6+
Auth,
7+
Description,
8+
EnvironmentRecord,
9+
GlobalConfig,
10+
Variables,
11+
} from "../schemas";
12+
import { FileTypeEnum } from "../types";
13+
import { TUnknown, Type } from "@sinclair/typebox";
14+
import { parseJsonContent, parseRaw } from "../common-utils";
15+
16+
export class ApiRecordFileType extends FileType<typeof ApiRecord> {
17+
validator = ApiRecord;
18+
19+
type = FileTypeEnum.API;
20+
21+
parse(content: string) {
22+
return parseJsonContent(content, this.validator);
23+
}
24+
}
25+
26+
export class EnvironmentRecordFileType extends FileType<
27+
typeof EnvironmentRecord
28+
> {
29+
validator = EnvironmentRecord;
30+
31+
type = FileTypeEnum.ENVIRONMENT;
32+
33+
parse(content: string) {
34+
return parseJsonContent(content, this.validator);
35+
}
36+
}
37+
38+
export class CollectionVariablesRecordFileType extends FileType<
39+
typeof Variables
40+
> {
41+
validator = Variables;
42+
43+
type = FileTypeEnum.COLLECTION_VARIABLES;
44+
45+
parse(content: string) {
46+
return parseJsonContent(content, this.validator);
47+
}
48+
}
49+
50+
export class ReadmeRecordFileType extends FileType<typeof Description> {
51+
validator = Description;
52+
53+
type = FileTypeEnum.DESCRIPTION;
54+
55+
parse(content: string) {
56+
return parseRaw(content, this.validator);
57+
}
58+
}
59+
60+
export class AuthRecordFileType extends FileType<typeof Auth> {
61+
validator = Auth;
62+
63+
type = FileTypeEnum.AUTH;
64+
65+
parse(content: string) {
66+
return parseJsonContent(content, this.validator);
67+
}
68+
}
69+
70+
export class GlobalConfigRecordFileType extends FileType<typeof GlobalConfig> {
71+
validator = GlobalConfig;
72+
73+
type = FileTypeEnum.GLOBAL_CONFIG;
74+
75+
parse(content: string) {
76+
return parseJsonContent(content, this.validator);
77+
}
78+
}
79+
80+
export class UnknownFileType extends FileType<TUnknown> {
81+
validator = Type.Unknown();
82+
83+
type = FileTypeEnum.UNKNOWN;
84+
85+
parse(content: string) {
86+
return parseRaw(content, this.validator);
87+
}
88+
}
89+
90+
export function parseFileType(type: string): FileType<any> {
91+
switch (type) {
92+
case FileTypeEnum.API:
93+
return new ApiRecordFileType();
94+
case FileTypeEnum.ENVIRONMENT:
95+
return new EnvironmentRecordFileType();
96+
case FileTypeEnum.COLLECTION_VARIABLES:
97+
return new CollectionVariablesRecordFileType();
98+
case FileTypeEnum.DESCRIPTION:
99+
return new ReadmeRecordFileType();
100+
case FileTypeEnum.AUTH:
101+
return new AuthRecordFileType();
102+
case FileTypeEnum.GLOBAL_CONFIG:
103+
return new GlobalConfigRecordFileType();
104+
case FileTypeEnum.UNKNOWN:
105+
return new UnknownFileType();
106+
default:
107+
throw new Error("Invalid file type!");
108+
}
109+
}

src/renderer/actions/local-sync/fs-manager.rpc-service.ts

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -117,5 +117,13 @@ export class FsManagerRPCService extends RPCServiceOverIPC {
117117
"updateCollectionAuthData",
118118
this.fsManager.updateCollectionAuthData.bind(this.fsManager)
119119
);
120+
this.exposeMethodOverIPC(
121+
"writeRawRecord",
122+
this.fsManager.writeRawRecord.bind(this.fsManager)
123+
);
124+
this.exposeMethodOverIPC(
125+
"getRawFileData",
126+
this.fsManager.getRawFileData.bind(this.fsManager)
127+
);
120128
}
121129
}

0 commit comments

Comments
 (0)