Skip to content

Commit ddf5354

Browse files
authored
BUG: Server actions throwing 500 on the FE server (#223)
* Return errors as value rather than thrown from the server * Add eror handling to the FE server * Fix lint * fix types
1 parent f79e659 commit ddf5354

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

55 files changed

+3042
-699
lines changed

frontend/actions/auth.ts

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,15 @@ export async function login(prevState: loginInitialState, formData: FormData) {
2222
}
2323

2424
const company = await getCompany();
25-
if (company?.externals) {
25+
if ("error" in company) {
26+
console.error("Error getting company:", company.error);
27+
return {
28+
success: false,
29+
message: company.error || "Login failed",
30+
};
31+
}
32+
const companyData = company.data;
33+
if (companyData?.externals) {
2634
importQuickbooksData();
2735
}
2836

frontend/api/business-profile.ts

Lines changed: 51 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -3,10 +3,15 @@ import { DocumentResponse, PresignedUploadResponse, DocumentCategories, Document
33
import { authHeader, authWrapper, getClient } from "./client";
44
import { getCompany } from "./company";
55
import { gzip } from "pako";
6+
import { ServerActionResult, isServerActionError } from "./types";
67

7-
export const getAllDocuments = async (): Promise<DocumentResponse[]> => {
8-
const req = async (token: string): Promise<DocumentResponse[]> => {
9-
const companyId = (await getCompany()).id;
8+
export const getAllDocuments = async (): Promise<ServerActionResult<DocumentResponse[]>> => {
9+
const req = async (token: string): Promise<ServerActionResult<DocumentResponse[]>> => {
10+
const companyResult = await getCompany();
11+
if (isServerActionError(companyResult)) {
12+
return { success: false, error: companyResult.error };
13+
}
14+
const companyId = companyResult.data.id;
1015
const documentType = DocumentTypes.GENERAL_BUSINESS;
1116

1217
const client = getClient();
@@ -22,21 +27,25 @@ export const getAllDocuments = async (): Promise<DocumentResponse[]> => {
2227
});
2328

2429
if (!response.ok || !data) {
25-
throw new Error(error?.error || "Failed to fetch documents");
30+
return { success: false, error: error?.error || "Failed to fetch documents" };
2631
}
2732

28-
return data;
33+
return { success: true, data };
2934
};
3035

31-
return authWrapper<DocumentResponse[]>()(req);
36+
return authWrapper<ServerActionResult<DocumentResponse[]>>()(req);
3237
};
3338

3439
export async function getBusinessDocumentUploadUrl(
3540
fileName: string,
3641
fileType: string
37-
): Promise<PresignedUploadResponse> {
38-
const req = async (token: string): Promise<PresignedUploadResponse> => {
39-
const companyId = (await getCompany()).id;
42+
): Promise<ServerActionResult<PresignedUploadResponse>> {
43+
const req = async (token: string): Promise<ServerActionResult<PresignedUploadResponse>> => {
44+
const companyResult = await getCompany();
45+
if (isServerActionError(companyResult)) {
46+
return { success: false, error: companyResult.error };
47+
}
48+
const companyId = companyResult.data.id;
4049
const client = getClient();
4150

4251
const { data, error, response } = await client.POST("/s3/getUploadUrl", {
@@ -50,23 +59,27 @@ export async function getBusinessDocumentUploadUrl(
5059
});
5160

5261
if (!response.ok || !data) {
53-
throw new Error(error?.error || "Failed to get upload URL");
62+
return { success: false, error: error?.error || "Failed to get upload URL" };
5463
}
5564

56-
return data;
65+
return { success: true, data };
5766
};
5867

59-
return authWrapper<PresignedUploadResponse>()(req);
68+
return authWrapper<ServerActionResult<PresignedUploadResponse>>()(req);
6069
}
6170

6271
export async function confirmBusinessDocumentUpload(
6372
key: string,
6473
documentId: string,
6574
category?: DocumentCategories
66-
): Promise<void> {
67-
const req = async (token: string): Promise<void> => {
75+
): Promise<ServerActionResult<void>> {
76+
const req = async (token: string): Promise<ServerActionResult<void>> => {
6877
const client = getClient();
69-
const companyId = (await getCompany()).id;
78+
const companyResult = await getCompany();
79+
if (isServerActionError(companyResult)) {
80+
return { success: false, error: companyResult.error };
81+
}
82+
const companyId = companyResult.data.id;
7083

7184
const { error, response } = await client.POST("/s3/confirmUpload", {
7285
headers: authHeader(token),
@@ -80,15 +93,20 @@ export async function confirmBusinessDocumentUpload(
8093
});
8194

8295
if (!response.ok) {
83-
throw new Error(error?.error || "Failed to confirm upload");
96+
return { success: false, error: error?.error || "Failed to confirm upload" };
8497
}
98+
99+
return { success: true, data: undefined };
85100
};
86101

87-
return authWrapper<void>()(req);
102+
return authWrapper<ServerActionResult<void>>()(req);
88103
}
89104

90-
export async function updateDocumentCategory(documentId: string, category: DocumentCategories): Promise<void> {
91-
const req = async (token: string): Promise<void> => {
105+
export async function updateDocumentCategory(
106+
documentId: string,
107+
category: DocumentCategories
108+
): Promise<ServerActionResult<void>> {
109+
const req = async (token: string): Promise<ServerActionResult<void>> => {
92110
const client = getClient();
93111

94112
const { error, response } = await client.PATCH("/s3/updateDocumentCategory", {
@@ -97,15 +115,17 @@ export async function updateDocumentCategory(documentId: string, category: Docum
97115
});
98116

99117
if (!response.ok) {
100-
throw new Error(error?.error || "Failed to update category");
118+
return { success: false, error: error?.error || "Failed to update category" };
101119
}
120+
121+
return { success: true, data: undefined };
102122
};
103123

104-
return authWrapper<void>()(req);
124+
return authWrapper<ServerActionResult<void>>()(req);
105125
}
106126

107-
export async function deleteBusinessDocument(key: string, documentId: string): Promise<void> {
108-
const req = async (token: string): Promise<void> => {
127+
export async function deleteBusinessDocument(key: string, documentId: string): Promise<ServerActionResult<void>> {
128+
const req = async (token: string): Promise<ServerActionResult<void>> => {
109129
const client = getClient();
110130

111131
const { error, response } = await client.DELETE("/s3/deleteDocument", {
@@ -114,14 +134,16 @@ export async function deleteBusinessDocument(key: string, documentId: string): P
114134
});
115135

116136
if (!response.ok) {
117-
throw new Error(error?.error || "Failed to delete document");
137+
return { success: false, error: error?.error || "Failed to delete document" };
118138
}
139+
140+
return { success: true, data: undefined };
119141
};
120142

121-
return authWrapper<void>()(req);
143+
return authWrapper<ServerActionResult<void>>()(req);
122144
}
123145

124-
export async function uploadToS3(uploadUrl: string, file: File): Promise<void> {
146+
export async function uploadToS3(uploadUrl: string, file: File): Promise<ServerActionResult<void>> {
125147
const arrayBuffer = await file.arrayBuffer();
126148
const compressed = gzip(new Uint8Array(arrayBuffer));
127149

@@ -135,6 +157,8 @@ export async function uploadToS3(uploadUrl: string, file: File): Promise<void> {
135157
});
136158

137159
if (!response.ok) {
138-
throw new Error(`Upload failed: ${response.statusText}`);
160+
return { success: false, error: `Upload failed: ${response.statusText}` };
139161
}
162+
163+
return { success: true, data: undefined };
140164
}

frontend/api/claim-location.ts

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2,21 +2,22 @@
22

33
import { authHeader, authWrapper, getClient } from "./client";
44
import { CreateClaimLocationRequest, CreateClaimLocationResponse } from "@/types/claim-location";
5+
import { ServerActionResult } from "./types";
56

67
export const createClaimLocationLink = async (
78
payload: CreateClaimLocationRequest
8-
): Promise<CreateClaimLocationResponse> => {
9-
const req = async (token: string): Promise<CreateClaimLocationResponse> => {
9+
): Promise<ServerActionResult<CreateClaimLocationResponse>> => {
10+
const req = async (token: string): Promise<ServerActionResult<CreateClaimLocationResponse>> => {
1011
const client = getClient();
1112
const { data, error, response } = await client.POST("/claim-locations", {
1213
headers: authHeader(token),
1314
body: payload,
1415
});
1516
if (response.ok) {
16-
return data!;
17+
return { success: true, data: data! };
1718
} else {
18-
throw Error(error?.error);
19+
return { success: false, error: error?.error || "Failed to create claim location link" };
1920
}
2021
};
21-
return authWrapper<CreateClaimLocationResponse>()(req);
22+
return authWrapper<ServerActionResult<CreateClaimLocationResponse>>()(req);
2223
};

0 commit comments

Comments
 (0)