authorgravatar for julius0216@outlook.comJulius Marminge <julius0216@outlook.com> 2026-06-20 10:56:12-07:00
committergravatar for noreply@github.comGitHub <noreply@github.com> 2026-06-20 10:56:12-07:00
logd87ec967bf5ef884486479e887e74307276d3e74
treeb3e5da709a275a09822ed33f4939fa42df098493
parente55dd0067dde55770a4f7f7d1720615fcfd56389
signature Signed by PGP key B5690EEEBB952194

[codex] Structure empty mobile pairing payload errors (#3372)

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

2 files changed, 18 insertions(+), 3 deletions(-)

apps/mobile/src/features/connection/pairing.test.ts+7-2
...@@ -1,6 +1,10 @@...@@ -1,6 +1,10 @@
1import { describe, expect, it } from "vite-plus/test";1import { describe, expect, it } from "vite-plus/test";
22
3import { extractPairingUrlFromQrPayload, parsePairingUrl } from "./pairing";3import {
4 extractPairingUrlFromQrPayload,
5 PairingQrPayloadEmptyError,
6 parsePairingUrl,
7} from "./pairing";
48
5describe("extractPairingUrlFromQrPayload", () => {9describe("extractPairingUrlFromQrPayload", () => {
6 it("trims raw pairing urls from qr payloads", () => {10 it("trims raw pairing urls from qr payloads", () => {
...@@ -18,7 +22,8 @@ describe("extractPairingUrlFromQrPayload", () => {...@@ -18,7 +22,8 @@ describe("extractPairingUrlFromQrPayload", () => {
18 });22 });
1923
20 it("rejects empty qr payloads", () => {24 it("rejects empty qr payloads", () => {
21 expect(() => extractPairingUrlFromQrPayload(" ")).toThrow(25 expect(() => extractPairingUrlFromQrPayload(" ")).toThrowError(PairingQrPayloadEmptyError);
26 expect(() => extractPairingUrlFromQrPayload(" ")).toThrowError(
22 "Scanned QR code did not contain a pairing URL.",27 "Scanned QR code did not contain a pairing URL.",
23 );28 );
24 });29 });
apps/mobile/src/features/connection/pairing.ts+11-1
...@@ -1,7 +1,17 @@...@@ -1,7 +1,17 @@
1import { readHostedPairingRequest } from "@t3tools/shared/remote";1import { readHostedPairingRequest } from "@t3tools/shared/remote";
2import * as Schema from "effect/Schema";
23
3const MOBILE_PAIRING_URL_PARAM = "pairingUrl";4const MOBILE_PAIRING_URL_PARAM = "pairingUrl";
45
6export class PairingQrPayloadEmptyError extends Schema.TaggedErrorClass<PairingQrPayloadEmptyError>()(
7 "PairingQrPayloadEmptyError",
8 {},
9) {
10 override get message(): string {
11 return "Scanned QR code did not contain a pairing URL.";
12 }
13}
14
5export function buildPairingUrl(host: string, code: string): string {15export function buildPairingUrl(host: string, code: string): string {
6 const h = host.trim();16 const h = host.trim();
7 const c = code.trim();17 const c = code.trim();
...@@ -48,7 +58,7 @@ export function parsePairingUrl(url: string): { host: string; code: string } {...@@ -48,7 +58,7 @@ export function parsePairingUrl(url: string): { host: string; code: string } {
48export function extractPairingUrlFromQrPayload(payload: string): string {58export function extractPairingUrlFromQrPayload(payload: string): string {
49 const trimmed = payload.trim();59 const trimmed = payload.trim();
50 if (!trimmed) {60 if (!trimmed) {
51 throw new Error("Scanned QR code did not contain a pairing URL.");61 throw new PairingQrPayloadEmptyError({});
52 }62 }
5363
54 try {64 try {