refactor(logging): centralize console output

This commit is contained in:
2026-06-18 13:34:19 +08:00
parent f600e11d55
commit 812a3e41b9
24 changed files with 261 additions and 166 deletions
+36 -34
View File
@@ -5,7 +5,7 @@
import { fromPromise, fromCallback } from "xstate";
import { createChatWebSocket, ChatWebSocket } from "@/core/net/chat-websocket";
import { Result } from "@/utils";
import { Result, Logger } from "@/utils";
import {
PAGE_SIZE,
@@ -17,6 +17,8 @@ import {
} from "./chat-machine.helpers";
import type { ChatEvent } from "./chat-events";
const log = new Logger("StoresChatChatMachineActors");
// ============================================================
// 共享 WS 引用(chatWebSocketActor ↔ sendMessageWsActor
// ============================================================
@@ -51,9 +53,9 @@ export const loadQuotaActor = fromPromise<{
remaining: number;
total: number;
}>(async () => {
console.log("[chat-machine] loadQuotaActor ENTRY");
log.debug("[chat-machine] loadQuotaActor ENTRY");
const result = await readGuestQuota();
console.log("[chat-machine] loadQuotaActor DONE", result);
log.debug("[chat-machine] loadQuotaActor DONE", result);
return result;
});
@@ -74,9 +76,9 @@ export const loadHistoryActor = fromPromise<{
localCount: number;
networkCount: number;
}>(async () => {
console.log("[chat-machine] loadHistoryActor ENTRY");
log.debug("[chat-machine] loadHistoryActor ENTRY");
const result = await readAndSyncHistory();
console.log("[chat-machine] loadHistoryActor DONE", {
log.debug("[chat-machine] loadHistoryActor DONE", {
finalCount: result.messages.length,
localCount: result.localCount,
networkCount: result.networkCount,
@@ -99,25 +101,25 @@ export const sendMessageHttpActor = fromPromise<
{ reply: UiMessage },
{ content: string }
>(async ({ input, self }) => {
console.log("[chat-machine] sendMessageHttpActor ENTRY", {
log.debug("[chat-machine] sendMessageHttpActor ENTRY", {
contentLength: input.content.length,
contentPreview: input.content.slice(0, 50),
selfId: self.id,
selfPath: "<actor path>",
});
console.log("[chat-machine] sendMessageHttpActor calling chatRepo.sendMessage");
log.debug("[chat-machine] sendMessageHttpActor calling chatRepo.sendMessage");
const result = await chatRepo.sendMessage(input.content);
console.log("[chat-machine] sendMessageHttpActor chatRepo.sendMessage DONE", {
log.debug("[chat-machine] sendMessageHttpActor chatRepo.sendMessage DONE", {
success: result.success,
error: result.success ? null : Result.isErr(result) ? result.error : null,
});
if (Result.isErr(result)) {
console.error("[chat-machine] sendMessageHttpActor result isErr, throwing");
log.error("[chat-machine] sendMessageHttpActor result isErr, throwing");
throw result.error;
}
// 一次发送 = 一次返回 —— 直接转 reply → UiMessage
console.log("[chat-machine] sendMessageHttpActor converting reply to UiMessage", {
log.debug("[chat-machine] sendMessageHttpActor converting reply to UiMessage", {
replyLength: result.data.reply.length,
replyPreview: result.data.reply.slice(0, 50),
messageId: result.data.messageId,
@@ -125,7 +127,7 @@ export const sendMessageHttpActor = fromPromise<
});
const reply = sendResponseToUiMessage(result.data);
console.log("[chat-machine] sendMessageHttpActor done", {
log.debug("[chat-machine] sendMessageHttpActor done", {
replyContentLength: reply.content.length,
});
return { reply };
@@ -136,37 +138,37 @@ export const loadMoreHistoryActor = fromPromise<
{ messages: UiMessage[]; hasMore: boolean; newOffset: number },
{ offset: number }
>(async ({ input, self }) => {
console.log("[chat-machine] loadMoreHistoryActor ENTRY", {
log.debug("[chat-machine] loadMoreHistoryActor ENTRY", {
inputOffset: input.offset,
pageSize: PAGE_SIZE,
selfPath: "<actor path>",
});
console.log("[chat-machine] loadMoreHistoryActor calling chatRepo.getHistory", {
log.debug("[chat-machine] loadMoreHistoryActor calling chatRepo.getHistory", {
pageSize: PAGE_SIZE,
offset: input.offset,
});
const result = await chatRepo.getHistory(PAGE_SIZE, input.offset);
console.log("[chat-machine] loadMoreHistoryActor chatRepo.getHistory DONE", {
log.debug("[chat-machine] loadMoreHistoryActor chatRepo.getHistory DONE", {
success: result.success,
error: result.success ? null : Result.isErr(result) ? result.error : null,
responseType: result.success ? typeof result.data : "err",
});
if (Result.isErr(result)) {
console.error("[chat-machine] loadMoreHistoryActor result isErr, throwing", {
log.error("[chat-machine] loadMoreHistoryActor result isErr, throwing", {
error: result.error,
});
throw result.error;
}
console.log("[chat-machine] loadMoreHistoryActor result data", {
log.debug("[chat-machine] loadMoreHistoryActor result data", {
rawMessagesCount: result.data.messages.length,
});
const page = localMessagesToUi(result.data.messages);
console.log("[chat-machine] loadMoreHistoryActor AFTER UiMessage mapping", {
log.debug("[chat-machine] loadMoreHistoryActor AFTER UiMessage mapping", {
uiMessagesCount: page.length,
});
const hasMore = page.length >= PAGE_SIZE;
const newOffset = input.offset + page.length;
console.log("[chat-machine] loadMoreHistoryActor result", {
log.debug("[chat-machine] loadMoreHistoryActor result", {
pageSize: page.length,
hasMore,
newOffset,
@@ -194,33 +196,33 @@ export const loadMoreHistoryActor = fromPromise<
*/
export const chatWebSocketActor = fromCallback<ChatEvent, { token: string }>(
({ sendBack, input }) => {
console.log("[chat-machine] chatWebSocketActor ENTRY", {
log.debug("[chat-machine] chatWebSocketActor ENTRY", {
hasToken: !!input.token,
tokenLength: input.token?.length ?? 0,
tokenPrefix: input.token?.slice(0, 10) ?? "EMPTY",
selfPath: "<actor path>",
});
console.log("[chat-machine] chatWebSocketActor creating ChatWebSocket instance");
log.debug("[chat-machine] chatWebSocketActor creating ChatWebSocket instance");
const ws = createChatWebSocket(input.token);
console.log("[chat-machine] chatWebSocketActor createChatWebSocket DONE", {
log.debug("[chat-machine] chatWebSocketActor createChatWebSocket DONE", {
wsType: ws.constructor.name,
});
// 写入 module-level 共享引用 —— sendMessageWsActor 借此调 ws.sendMessage()
activeChatWebSocket = ws;
console.log("[chat-machine] chatWebSocketActor activeChatWebSocket SET", {
log.debug("[chat-machine] chatWebSocketActor activeChatWebSocket SET", {
isConnected: ws.isConnected,
});
ws.onConnected = (userId) => {
console.log("[chat-machine] WS onConnected", {
log.debug("[chat-machine] WS onConnected", {
userId,
userIdPrefix: userId?.slice(0, 8) ?? "EMPTY",
});
sendBack({ type: "ChatWebSocketConnected", userId });
};
ws.onSentence = (p) => {
console.log("[chat-machine] WS onSentence", {
log.debug("[chat-machine] WS onSentence", {
index: p.index,
total: p.total,
done: p.done,
@@ -237,23 +239,23 @@ export const chatWebSocketActor = fromCallback<ChatEvent, { token: string }>(
});
};
ws.onError = (msg) => {
console.error("[chat-machine] WS onError", {
log.error("[chat-machine] WS onError", {
errorMessage: msg,
errorLength: msg?.length ?? 0,
});
sendBack({ type: "ChatWebSocketError", errorMessage: msg });
};
console.log("[chat-machine] chatWebSocketActor calling ws.connect()");
log.debug("[chat-machine] chatWebSocketActor calling ws.connect()");
ws.connect();
console.log("[chat-machine] chatWebSocketActor ws.connect() called");
log.debug("[chat-machine] chatWebSocketActor ws.connect() called");
return () => {
console.log(
log.debug(
"[chat-machine] chatWebSocketActor CLEANUP (parent state exit / logout / cross-transition / unmount)",
);
// 清空 module-level 引用 —— 严格用 `=== ws` 判等,避免覆盖更新的实例
if (activeChatWebSocket === ws) {
activeChatWebSocket = null;
console.log("[chat-machine] chatWebSocketActor activeChatWebSocket CLEARED");
log.debug("[chat-machine] chatWebSocketActor activeChatWebSocket CLEARED");
}
ws.disconnect();
};
@@ -281,26 +283,26 @@ export const chatWebSocketActor = fromCallback<ChatEvent, { token: string }>(
*/
export const sendMessageWsActor = fromPromise<void, { content: string }>(
async ({ input }) => {
console.log("[chat-machine] sendMessageWsActor ENTRY", {
log.debug("[chat-machine] sendMessageWsActor ENTRY", {
contentLength: input.content.length,
contentPreview: input.content.slice(0, 50),
});
const ws = getActiveChatWebSocket();
if (!ws) {
console.error("[chat-machine] sendMessageWsActor no activeChatWebSocket");
log.error("[chat-machine] sendMessageWsActor no activeChatWebSocket");
throw new Error("[chat-machine] sendMessageWs: no active WebSocket (actor not running)");
}
console.log("[chat-machine] sendMessageWsActor calling ws.sendMessage", {
log.debug("[chat-machine] sendMessageWsActor calling ws.sendMessage", {
isConnected: ws.isConnected,
});
const ok = ws.sendMessage(input.content);
if (!ok) {
console.error(
log.error(
"[chat-machine] sendMessageWsActor ws.sendMessage returned false (not OPEN)",
);
throw new Error("[chat-machine] sendMessageWs: WebSocket not OPEN");
}
console.log(
log.debug(
"[chat-machine] sendMessageWsActor ws.sendMessage OK, awaiting AI sentence stream",
);
// resolve 不返值 —— AI reply 由 chatWebSocketActor 的 ChatAISentenceReceived 流回