Skip to content

Commit

Permalink
add more verbose logs
Browse files Browse the repository at this point in the history
  • Loading branch information
erquhart committed Jan 27, 2025
1 parent 3f46b0a commit 2a6404d
Show file tree
Hide file tree
Showing 5 changed files with 84 additions and 8 deletions.
19 changes: 19 additions & 0 deletions src/browser/sync/authentication_manager.ts
Original file line number Diff line number Diff line change
Expand Up @@ -206,6 +206,9 @@ export class AuthenticationManager {
// in that we pause the WebSocket so that mutations
// don't retry with bad auth.
private async tryToReauthenticate(serverMessage: AuthError) {
this._logVerbose(
`trying to reauthenticate: ${JSON.stringify(serverMessage)}`,
);
// We only retry once, to avoid infinite retries
if (
// No way to fetch another token, kaboom
Expand Down Expand Up @@ -374,9 +377,13 @@ export class AuthenticationManager {
},
) {
const originalConfigVersion = ++this.configVersion;
this._logVerbose("fetching auth token");
const token = await fetchToken(fetchArgs);
if (this.configVersion !== originalConfigVersion) {
// This is a stale config
this._logVerbose(
`stale config version, expected ${originalConfigVersion}`,
);
return { isFromOutdatedConfig: true };
}
return { isFromOutdatedConfig: false, value: token };
Expand All @@ -386,6 +393,7 @@ export class AuthenticationManager {
this.resetAuthState();
// Bump this in case we are mid-token-fetch when we get stopped
this.configVersion++;
this._logVerbose(`config version bumped`);
}

private setAndReportAuthFailed(
Expand All @@ -400,6 +408,17 @@ export class AuthenticationManager {
}

private setAuthState(newAuth: AuthState) {
const authStateForLog =
newAuth.state === "waitingForServerConfirmationOfFreshToken"
? {
...newAuth,
token: `...${newAuth.token.slice(-5)}`,
}
: newAuth;
this._logVerbose(
`setting auth state to ${JSON.stringify(authStateForLog)}`,
);

if (this.authState.state === "waitingForScheduledRefetch") {
clearTimeout(this.authState.refetchTokenTimeoutId);

Expand Down
44 changes: 36 additions & 8 deletions src/browser/sync/web_socket_manager.ts
Original file line number Diff line number Diff line change
Expand Up @@ -158,6 +158,15 @@ export class WebSocketManager {
this.connect();
}

private setSocketState(state: Socket) {
this.socket = state;
this._logVerbose(
`socket state changed: ${this.socket.state}, paused: ${
"paused" in this.socket ? this.socket.paused : undefined
}`,
);
}

private connect() {
if (this.socket.state === "terminated") {
return;
Expand All @@ -173,11 +182,11 @@ export class WebSocketManager {

const ws = new this.webSocketConstructor(this.uri);
this._logVerbose("constructed WebSocket");
this.socket = {
this.setSocketState({
state: "connecting",
ws,
paused: "no",
};
});

// Kick off server inactivity timer before WebSocket connection is established
// so we can detect cases where handshake fails.
Expand All @@ -190,11 +199,11 @@ export class WebSocketManager {
if (this.socket.state !== "connecting") {
throw new Error("onopen called with socket not in connecting state");
}
this.socket = {
this.setSocketState({
state: "ready",
ws,
paused: this.socket.paused === "yes" ? "uninitialized" : "no",
};
});
this.resetServerInactivityTimeout();
if (this.socket.paused === "no") {
this.onOpen({
Expand Down Expand Up @@ -259,8 +268,14 @@ export class WebSocketManager {
* @returns Whether the message (might have been) sent.
*/
sendMessage(message: ClientMessage) {
this._logVerbose(`sending message with type ${message.type}`);

const messageForLog = {
type: message.type,
...(message.type === "Authenticate" && message.tokenType === "User"
? {
value: `...${message.value.slice(-5)}`,
}
: {}),
};
if (this.socket.state === "ready" && this.socket.paused === "no") {
const encodedMessage = encodeClientMessage(message);
const request = JSON.stringify(encodedMessage);
Expand All @@ -273,8 +288,19 @@ export class WebSocketManager {
this.closeAndReconnect("FailedToSendMessage");
}
// We are not sure if this was sent or not.
this._logVerbose(
`sent message with type ${message.type}: ${JSON.stringify(
messageForLog,
)}`,
);
return true;
}
this._logVerbose(
`message not sent (socket state: ${this.socket.state}, paused: ${"paused" in this.socket ? this.socket.paused : undefined}): ${JSON.stringify(
messageForLog,
)}`,
);

return false;
}

Expand Down Expand Up @@ -305,7 +331,9 @@ export class WebSocketManager {
* This should be used when we hit an error and would like to restart the session.
*/
private closeAndReconnect(closeReason: string) {
this._logVerbose(`begin closeAndReconnect with reason ${closeReason}`);
this._logVerbose(
`begin closeAndReconnect with reason ${closeReason}, socket state: ${this.socket.state}`,
);
switch (this.socket.state) {
case "disconnected":
case "terminated":
Expand Down Expand Up @@ -388,7 +416,7 @@ export class WebSocketManager {
case "connecting":
case "ready": {
const result = this.close();
this.socket = { state: "terminated" };
this.setSocketState({ state: "terminated" });
return result;
}
default: {
Expand Down
2 changes: 2 additions & 0 deletions src/react-auth0/ConvexProviderWithAuth0.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,14 @@ import React from "react";
import { ReactNode, useCallback, useMemo } from "react";
import { AuthTokenFetcher } from "../browser/sync/client.js";
import { ConvexProviderWithAuth } from "../react/ConvexAuthState.js";
import { Logger } from "../browser/logging.js";

// Until we can import from our own entry points (requires TypeScript 4.7),
// just describe the interface enough to help users pass the right type.
type IConvexReactClient = {
setAuth(fetchToken: AuthTokenFetcher): void;
clearAuth(): void;
logger: Logger;
};

/**
Expand Down
2 changes: 2 additions & 0 deletions src/react-clerk/ConvexProviderWithClerk.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,14 @@ import React from "react";
import { ReactNode, useCallback, useMemo } from "react";
import { AuthTokenFetcher } from "../browser/sync/client.js";
import { ConvexProviderWithAuth } from "../react/ConvexAuthState.js";
import { Logger } from "../browser/logging.js";

// Until we can import from our own entry points (requires TypeScript 4.7),
// just describe the interface enough to help users pass the right type.
type IConvexReactClient = {
setAuth(fetchToken: AuthTokenFetcher): void;
clearAuth(): void;
logger: Logger;
};

// https://clerk.com/docs/reference/clerk-react/useauth
Expand Down
25 changes: 25 additions & 0 deletions src/react/ConvexAuthState.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import React, {
} from "react";
import { AuthTokenFetcher } from "../browser/sync/client.js";
import { ConvexProvider } from "./client.js";
import { Logger } from "../browser/logging.js";

// Until we can import from our own entry points (requires TypeScript 4.7),
// just describe the interface enough to help users pass the right type.
Expand All @@ -16,6 +17,7 @@ type IConvexReactClient = {
onChange: (isAuthenticated: boolean) => void,
): void;
clearAuth(): void;
logger: Logger;
};

/**
Expand Down Expand Up @@ -113,6 +115,29 @@ export function ConvexProviderWithAuth({
setIsConvexAuthenticated(false);
}

useEffect(() => {
client.logger.logVerbose(
"auth state changed",
JSON.stringify(
{
authProviderLoading,
authProviderAuthenticated,
isConvexAuthenticated,
isLoading: isConvexAuthenticated === null,
isAuthenticated:
authProviderAuthenticated && (isConvexAuthenticated ?? false),
},
null,
2,
),
);
}, [
authProviderLoading,
authProviderAuthenticated,
isConvexAuthenticated,
client.logger,
]);

return (
<ConvexAuthContext.Provider
value={{
Expand Down

0 comments on commit 2a6404d

Please sign in to comment.