chore(auth): add debug logging to guest login flow
Add console.log instrumentation across the guest login pipeline (auth-machine, authRepository, authApi) to trace request lifecycle and surface Zod parsing failures with detailed issue info. Useful for diagnosing lastMessageAt schema mismatches.
This commit is contained in:
@@ -123,16 +123,31 @@ export class AuthRepository implements IAuthRepository {
|
|||||||
* 成功后写 guest token + deviceId + userId。
|
* 成功后写 guest token + deviceId + userId。
|
||||||
*/
|
*/
|
||||||
async guestLogin(deviceId: string): Promise<Result<GuestLoginResponse>> {
|
async guestLogin(deviceId: string): Promise<Result<GuestLoginResponse>> {
|
||||||
|
console.log("[AuthRepository.guestLogin] API call START", {
|
||||||
|
deviceIdLength: deviceId.length,
|
||||||
|
deviceIdPrefix: deviceId.slice(0, 8),
|
||||||
|
});
|
||||||
return Result.wrap(async () => {
|
return Result.wrap(async () => {
|
||||||
const response = await this.api.guestLogin(
|
const response = await this.api.guestLogin(
|
||||||
GuestLoginRequest.from({ deviceId }),
|
GuestLoginRequest.from({ deviceId }),
|
||||||
);
|
);
|
||||||
|
console.log("[AuthRepository.guestLogin] API call SUCCESS (Zod parsed)", {
|
||||||
|
hasToken: !!response.token,
|
||||||
|
hasUser: !!response.user,
|
||||||
|
userLastMessageAt: response.user?.lastMessageAt,
|
||||||
|
});
|
||||||
await this.storage.setGuestToken(response.token);
|
await this.storage.setGuestToken(response.token);
|
||||||
await this.storage.setDeviceId(deviceId);
|
await this.storage.setDeviceId(deviceId);
|
||||||
if (response.userId) {
|
if (response.userId) {
|
||||||
await this.userStorage.setUserId(response.userId);
|
await this.userStorage.setUserId(response.userId);
|
||||||
}
|
}
|
||||||
return response;
|
return response;
|
||||||
|
}).catch((e) => {
|
||||||
|
console.error("[AuthRepository.guestLogin] API call FAILED", {
|
||||||
|
errorName: e?.name,
|
||||||
|
errorMessage: e?.message,
|
||||||
|
});
|
||||||
|
return Result.err(e);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -4,6 +4,8 @@
|
|||||||
* 认证相关接口
|
* 认证相关接口
|
||||||
* 原始 Dart: lib/data/services/api/auth_api_client.dart
|
* 原始 Dart: lib/data/services/api/auth_api_client.dart
|
||||||
*/
|
*/
|
||||||
|
import { z } from "zod";
|
||||||
|
|
||||||
import { httpClient } from "./http_client";
|
import { httpClient } from "./http_client";
|
||||||
import { ApiPath } from "./api_path";
|
import { ApiPath } from "./api_path";
|
||||||
import { ApiEnvelope, unwrap } from "./response_helper";
|
import { ApiEnvelope, unwrap } from "./response_helper";
|
||||||
@@ -117,7 +119,29 @@ export class AuthApi {
|
|||||||
method: "POST",
|
method: "POST",
|
||||||
body: body.toJson(),
|
body: body.toJson(),
|
||||||
});
|
});
|
||||||
return GuestLoginResponse.fromJson(unwrap(env) as Record<string, unknown>);
|
console.log("[AuthApi.guestLogin] raw envelope from backend", env);
|
||||||
|
const unwrapped = unwrap(env) as Record<string, unknown>;
|
||||||
|
const userObj = unwrapped.user as { lastMessageAt?: unknown } | undefined;
|
||||||
|
console.log("[AuthApi.guestLogin] unwrapped data (pre-parse)", {
|
||||||
|
hasUser: "user" in unwrapped,
|
||||||
|
userKeys: userObj && typeof userObj === "object" ? Object.keys(userObj) : null,
|
||||||
|
lastMessageAt: userObj?.lastMessageAt,
|
||||||
|
lastMessageAtType: typeof userObj?.lastMessageAt,
|
||||||
|
});
|
||||||
|
try {
|
||||||
|
return GuestLoginResponse.fromJson(unwrapped);
|
||||||
|
} catch (e) {
|
||||||
|
if (e instanceof z.ZodError) {
|
||||||
|
console.error("[AuthApi.guestLogin] ZodError parsing response", {
|
||||||
|
issueCount: e.issues.length,
|
||||||
|
firstIssue: e.issues[0],
|
||||||
|
allPaths: e.issues.map((i) => i.path),
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
console.error("[AuthApi.guestLogin] unexpected error", e);
|
||||||
|
}
|
||||||
|
throw e;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -120,16 +120,35 @@ const syncFacebookBackendActor = fromPromise<
|
|||||||
// 受保护 API 401 会由 HTTP 层清掉 token 回到 splash,无需在此处主动校验。
|
// 受保护 API 401 会由 HTTP 层清掉 token 回到 splash,无需在此处主动校验。
|
||||||
|
|
||||||
const guestLoginActor = fromPromise<LoginStatus, void>(async () => {
|
const guestLoginActor = fromPromise<LoginStatus, void>(async () => {
|
||||||
|
console.log("[auth-machine] guestLoginActor ENTRY");
|
||||||
|
|
||||||
// 1. 先查本地 guestToken —— 已有就直接进 idle(带 pendingRedirect)
|
// 1. 先查本地 guestToken —— 已有就直接进 idle(带 pendingRedirect)
|
||||||
const hasTokenR = await AuthStorage.getInstance().hasGuestToken();
|
const hasTokenR = await AuthStorage.getInstance().hasGuestToken();
|
||||||
|
console.log("[auth-machine] guestLoginActor hasGuestToken", {
|
||||||
|
success: hasTokenR.success,
|
||||||
|
hasData: hasTokenR.success ? !!hasTokenR.data : null,
|
||||||
|
});
|
||||||
if (hasTokenR.success && hasTokenR.data) {
|
if (hasTokenR.success && hasTokenR.data) {
|
||||||
|
console.log("[auth-machine] guestLoginActor SHORT-CIRCUIT (has local guestToken) → return guest");
|
||||||
return "guest" as LoginStatus;
|
return "guest" as LoginStatus;
|
||||||
}
|
}
|
||||||
// Result.err(_) 时**不**抛 —— 落到 API 路径让真正的错误信号出现
|
// Result.err(_) 时**不**抛 —— 落到 API 路径让真正的错误信号出现
|
||||||
|
|
||||||
// 2. 没有(或读不出)才走完整流程:拿 deviceId → 调后端
|
// 2. 没有(或读不出)才走完整流程:拿 deviceId → 调后端
|
||||||
const deviceId = await deviceIdentifier.getDeviceId();
|
const deviceId = await deviceIdentifier.getDeviceId();
|
||||||
|
console.log("[auth-machine] guestLoginActor deviceId", {
|
||||||
|
length: deviceId.length,
|
||||||
|
prefix: deviceId.slice(0, 8),
|
||||||
|
});
|
||||||
|
|
||||||
|
console.log("[auth-machine] guestLoginActor calling authRepository.guestLogin");
|
||||||
const result = await authRepository.guestLogin(deviceId);
|
const result = await authRepository.guestLogin(deviceId);
|
||||||
|
console.log("[auth-machine] guestLoginActor authRepository.guestLogin DONE", {
|
||||||
|
success: result.success,
|
||||||
|
hasData: result.success ? !!result.data : null,
|
||||||
|
errorName: result.success ? null : result.error?.name,
|
||||||
|
errorMessage: result.success ? null : result.error?.message,
|
||||||
|
});
|
||||||
if (Result.isErr(result)) throw result.error;
|
if (Result.isErr(result)) throw result.error;
|
||||||
return "guest" as LoginStatus;
|
return "guest" as LoginStatus;
|
||||||
});
|
});
|
||||||
|
|||||||
Reference in New Issue
Block a user