authorgravatar for julius0216@outlook.comJulius Marminge <julius0216@outlook.com> 2026-06-20 11:03:09-07:00
committergravatar for noreply@github.comGitHub <noreply@github.com> 2026-06-20 11:03:09-07:00
logf3b43a148b9e39192be5d43415289ac06eca1443
treefc64290a0de808a540049bc73aa28323870ecbb5
parent8331511b972242301bdaec328148a88b9b6cfa6c
signature Signed by PGP key B5690EEEBB952194

[codex] Structure missing client cloud config errors (#3346)

Co-authored-by: codex <codex@users.noreply.github.com>

4 files changed, 51 insertions(+), 4 deletions(-)

apps/mobile/src/features/cloud/publicConfig.test.ts+12-1
......@@ -1,6 +1,11 @@
11import { describe, expect, it, vi } from "vite-plus/test";
22
3import { hasTracingPublicConfig, resolveCloudPublicConfig } from "./publicConfig";
3import {
4 CloudPublicConfigMissingError,
5 hasTracingPublicConfig,
6 resolveCloudPublicConfig,
7 resolveRelayClerkTokenOptions,
8} from "./publicConfig";
49
510vi.mock("expo-constants", () => ({
611 default: {
......@@ -11,6 +16,12 @@ vi.mock("expo-constants", () => ({
1116}));
1217
1318describe("resolveCloudPublicConfig", () => {
19 it("reports the missing Clerk JWT template as structured configuration", () => {
20 expect(() => resolveRelayClerkTokenOptions()).toThrowError(
21 new CloudPublicConfigMissingError({ key: "T3CODE_CLERK_JWT_TEMPLATE" }),
22 );
23 });
24
1425 it("returns no cloud configuration for an unconfigured build", () => {
1526 expect(resolveCloudPublicConfig({})).toEqual({
1627 clerk: {
apps/mobile/src/features/cloud/publicConfig.ts+13-1
......@@ -1,6 +1,18 @@
11import Constants from "expo-constants";
22import { relayClerkTokenOptions } from "@t3tools/shared/relayAuth";
33import { normalizeSecureRelayUrl } from "@t3tools/shared/relayUrl";
4import * as Schema from "effect/Schema";
5
6export class CloudPublicConfigMissingError extends Schema.TaggedErrorClass<CloudPublicConfigMissingError>()(
7 "CloudPublicConfigMissingError",
8 {
9 key: Schema.Literal("T3CODE_CLERK_JWT_TEMPLATE"),
10 },
11) {
12 override get message(): string {
13 return `${this.key} is not configured.`;
14 }
15}
416
517export interface CloudPublicConfig {
618 readonly clerk: {
......@@ -87,7 +99,7 @@ export function hasTracingPublicConfig(
8799export function resolveRelayClerkTokenOptions() {
88100 const { jwtTemplate } = resolveCloudPublicConfig().clerk;
89101 if (!jwtTemplate) {
90 throw new Error("T3CODE_CLERK_JWT_TEMPLATE is not configured.");
102 throw new CloudPublicConfigMissingError({ key: "T3CODE_CLERK_JWT_TEMPLATE" });
91103 }
92104 return relayClerkTokenOptions(jwtTemplate);
93105}
apps/web/src/cloud/publicConfig.test.ts+13-1
......@@ -1,6 +1,10 @@
11import { afterEach, describe, expect, it, vi } from "vite-plus/test";
22
3import { hasCloudPublicConfig } from "./publicConfig.ts";
3import {
4 CloudPublicConfigMissingError,
5 hasCloudPublicConfig,
6 resolveRelayClerkTokenOptions,
7} from "./publicConfig.ts";
48
59afterEach(() => {
610 vi.unstubAllEnvs();
......@@ -30,4 +34,12 @@ describe("hasCloudPublicConfig", () => {
3034
3135 expect(hasCloudPublicConfig()).toBe(false);
3236 });
37
38 it("reports the missing Clerk JWT template as structured configuration", () => {
39 vi.stubEnv("VITE_CLERK_JWT_TEMPLATE", "");
40
41 expect(() => resolveRelayClerkTokenOptions()).toThrowError(
42 new CloudPublicConfigMissingError({ key: "T3CODE_CLERK_JWT_TEMPLATE" }),
43 );
44 });
3345});
apps/web/src/cloud/publicConfig.ts+13-1
......@@ -1,5 +1,17 @@
11import { relayClerkTokenOptions } from "@t3tools/shared/relayAuth";
22import { normalizeSecureRelayUrl } from "@t3tools/shared/relayUrl";
3import * as Schema from "effect/Schema";
4
5export class CloudPublicConfigMissingError extends Schema.TaggedErrorClass<CloudPublicConfigMissingError>()(
6 "CloudPublicConfigMissingError",
7 {
8 key: Schema.Literal("T3CODE_CLERK_JWT_TEMPLATE"),
9 },
10) {
11 override get message(): string {
12 return `${this.key} is not configured.`;
13 }
14}
315
416export interface CloudPublicConfig {
517 readonly clerkPublishableKey: string | null;
......@@ -65,7 +77,7 @@ export function hasCloudPublicConfig(): boolean {
6577export function resolveRelayClerkTokenOptions() {
6678 const { clerkJwtTemplate } = resolveCloudPublicConfig();
6779 if (!clerkJwtTemplate) {
68 throw new Error("T3CODE_CLERK_JWT_TEMPLATE is not configured.");
80 throw new CloudPublicConfigMissingError({ key: "T3CODE_CLERK_JWT_TEMPLATE" });
6981 }
7082 return relayClerkTokenOptions(clerkJwtTemplate);
7183}