Skip to content

Commit a22843c

Browse files
committed
wip
1 parent 4434a30 commit a22843c

2 files changed

Lines changed: 77 additions & 24 deletions

File tree

apps/code/src/renderer/api/posthogClient.ts

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1291,12 +1291,11 @@ export class PostHogAPIClient {
12911291
const parsed = this.parseFetcherError(error);
12921292

12931293
if (parsed) {
1294-
if (parsed.status === 400) {
1295-
const redirectUrl =
1296-
typeof parsed.body.redirect_url === "string"
1297-
? parsed.body.redirect_url
1298-
: `${this.api.baseUrl}/organization/billing`;
1299-
throw new SeatSubscriptionRequiredError(redirectUrl);
1294+
if (
1295+
parsed.status === 400 &&
1296+
typeof parsed.body.redirect_url === "string"
1297+
) {
1298+
throw new SeatSubscriptionRequiredError(parsed.body.redirect_url);
13001299
}
13011300
if (parsed.status === 402) {
13021301
const message =

apps/code/src/renderer/features/billing/stores/seatStore.ts

Lines changed: 72 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
11
import { useAuthStore } from "@features/auth/stores/authStore";
2-
import type { SeatSubscriptionRequiredError } from "@renderer/api/posthogClient";
32
import type { SeatData } from "@shared/types/seat";
43
import { PLAN_FREE, PLAN_PRO } from "@shared/types/seat";
54
import { electronStorage } from "@utils/electronStorage";
@@ -36,32 +35,70 @@ function getClient() {
3635
return client;
3736
}
3837

38+
function parseFetcherError(
39+
error: Error,
40+
): { status: number; body: Record<string, unknown> } | null {
41+
const match = error.message.match(/\[(\d+)\]\s*(.*)/);
42+
if (!match) return null;
43+
try {
44+
return {
45+
status: Number.parseInt(match[1], 10),
46+
body: JSON.parse(match[2]) as Record<string, unknown>,
47+
};
48+
} catch {
49+
return { status: Number.parseInt(match[1], 10), body: {} };
50+
}
51+
}
52+
3953
function handleSeatError(
4054
error: unknown,
4155
set: (state: Partial<SeatStoreState>) => void,
4256
): void {
43-
if (error instanceof Error) {
44-
if (
45-
error.name === "SeatSubscriptionRequiredError" &&
46-
"redirectUrl" in error
47-
) {
57+
if (!(error instanceof Error)) {
58+
log.error("Seat operation failed", error);
59+
set({ isLoading: false, error: "An unexpected error occurred" });
60+
return;
61+
}
62+
63+
if (
64+
"redirectUrl" in error &&
65+
typeof (error as { redirectUrl: unknown }).redirectUrl === "string"
66+
) {
67+
set({
68+
isLoading: false,
69+
error: "Billing subscription required",
70+
redirectUrl: (error as { redirectUrl: string }).redirectUrl,
71+
});
72+
return;
73+
}
74+
75+
const parsed = parseFetcherError(error);
76+
if (parsed) {
77+
if (parsed.status === 400 && typeof parsed.body.redirect_url === "string") {
4878
set({
4979
isLoading: false,
50-
error: "Billing subscription required",
51-
redirectUrl: (error as SeatSubscriptionRequiredError).redirectUrl,
80+
error:
81+
typeof parsed.body.error === "string"
82+
? parsed.body.error
83+
: "Billing subscription required",
84+
redirectUrl: parsed.body.redirect_url,
5285
});
5386
return;
5487
}
55-
if (error.name === "SeatPaymentFailedError") {
56-
set({ isLoading: false, error: error.message });
88+
if (parsed.status === 402) {
89+
set({
90+
isLoading: false,
91+
error:
92+
typeof parsed.body.error === "string"
93+
? parsed.body.error
94+
: "Payment failed",
95+
});
5796
return;
5897
}
59-
log.error("Seat operation failed", error);
60-
set({ isLoading: false, error: error.message });
61-
return;
6298
}
99+
63100
log.error("Seat operation failed", error);
64-
set({ isLoading: false, error: "An unexpected error occurred" });
101+
set({ isLoading: false, error: error.message });
65102
}
66103

67104
const initialState: SeatStoreState = {
@@ -91,6 +128,16 @@ export const useSeatStore = create<SeatStore>()(
91128
set({ isLoading: true, error: null, redirectUrl: null });
92129
try {
93130
const client = getClient();
131+
const existing = await client.getMySeat();
132+
if (existing) {
133+
if (existing.plan_key === PLAN_FREE) {
134+
set({ seat: existing, isLoading: false });
135+
return;
136+
}
137+
const seat = await client.upgradeSeat(PLAN_FREE);
138+
set({ seat, isLoading: false });
139+
return;
140+
}
94141
const seat = await client.createSeat(PLAN_FREE);
95142
set({ seat, isLoading: false });
96143
} catch (error) {
@@ -102,10 +149,17 @@ export const useSeatStore = create<SeatStore>()(
102149
set({ isLoading: true, error: null, redirectUrl: null });
103150
try {
104151
const client = getClient();
105-
const currentSeat = useSeatStore.getState().seat;
106-
const seat = currentSeat
107-
? await client.upgradeSeat(PLAN_PRO)
108-
: await client.createSeat(PLAN_PRO);
152+
const existing = await client.getMySeat();
153+
if (existing) {
154+
if (existing.plan_key === PLAN_PRO) {
155+
set({ seat: existing, isLoading: false });
156+
return;
157+
}
158+
const seat = await client.upgradeSeat(PLAN_PRO);
159+
set({ seat, isLoading: false });
160+
return;
161+
}
162+
const seat = await client.createSeat(PLAN_PRO);
109163
set({ seat, isLoading: false });
110164
} catch (error) {
111165
handleSeatError(error, set);

0 commit comments

Comments
 (0)