mirror of
https://github.com/better-auth/better-auth.git
synced 2026-10-19 11:24:57 -05:00
fix(logger): respect configured logger in auth request context
This commit is contained in:
@@ -0,0 +1,5 @@
|
||||
---
|
||||
"@better-auth/core": patch
|
||||
---
|
||||
|
||||
Logs emitted while handling auth requests now respect the configured custom logger, log level, and disabled setting.
|
||||
@@ -32,6 +32,18 @@ export async function getCurrentAuthContextAsyncLocalStorage() {
|
||||
return ensureAsyncStorage();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the current auth context without initializing async storage.
|
||||
*
|
||||
* @internal
|
||||
*/
|
||||
export function tryGetCurrentAuthContext(): AuthEndpointContext | undefined {
|
||||
const storage = __getBetterAuthGlobal().context.endpointContextAsyncStorage as
|
||||
| AsyncLocalStorage<AuthEndpointContext>
|
||||
| undefined;
|
||||
return storage?.getStore();
|
||||
}
|
||||
|
||||
export async function getCurrentAuthContext(): Promise<AuthEndpointContext> {
|
||||
const als = await ensureAsyncStorage();
|
||||
const context = als.getStore();
|
||||
|
||||
Vendored
+80
-3
@@ -1,6 +1,9 @@
|
||||
import { describe, expect, it } from "vitest";
|
||||
import type { LogLevel } from "./logger";
|
||||
import { shouldPublishLog } from "./logger";
|
||||
import { describe, expect, it, onTestFinished, vi } from "vitest";
|
||||
import type { AuthEndpointContext } from "../context";
|
||||
import { runWithEndpointContext } from "../context";
|
||||
import { safeJSONParse } from "../utils/json";
|
||||
import type { InternalLogger, LogLevel } from "./logger";
|
||||
import { createLogger, logger, shouldPublishLog } from "./logger";
|
||||
|
||||
describe("shouldPublishLog", () => {
|
||||
const testCases: {
|
||||
@@ -32,3 +35,77 @@ describe("shouldPublishLog", () => {
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe("logger", () => {
|
||||
const endpointContext = (logger: InternalLogger) =>
|
||||
({ context: { logger } }) as unknown as AuthEndpointContext;
|
||||
|
||||
it("uses the default logger outside an auth context", () => {
|
||||
const defaultWarn = vi.spyOn(console, "warn").mockImplementation(() => {});
|
||||
onTestFinished(() => defaultWarn.mockRestore());
|
||||
|
||||
logger.warn("default warning");
|
||||
|
||||
expect(defaultWarn).toHaveBeenCalledTimes(1);
|
||||
});
|
||||
|
||||
it("delegates to the logger in the current auth context", async () => {
|
||||
const defaultWarn = vi.spyOn(console, "warn").mockImplementation(() => {});
|
||||
onTestFinished(() => defaultWarn.mockRestore());
|
||||
const firstLog = vi.fn();
|
||||
const secondLog = vi.fn();
|
||||
const firstLogger = createLogger({ level: "info", log: firstLog });
|
||||
const secondLogger = createLogger({ level: "error", log: secondLog });
|
||||
|
||||
await Promise.all([
|
||||
runWithEndpointContext(endpointContext(firstLogger), async () => {
|
||||
await Promise.resolve();
|
||||
expect(logger.level).toBe("info");
|
||||
logger.warn("first warning");
|
||||
}),
|
||||
runWithEndpointContext(endpointContext(secondLogger), async () => {
|
||||
await Promise.resolve();
|
||||
expect(logger.level).toBe("error");
|
||||
logger.warn("second warning");
|
||||
}),
|
||||
]);
|
||||
|
||||
expect(firstLog).toHaveBeenCalledWith("warn", "first warning");
|
||||
expect(secondLog).not.toHaveBeenCalled();
|
||||
expect(defaultWarn).not.toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it("routes utility logs through the current auth context", async () => {
|
||||
const defaultError = vi
|
||||
.spyOn(console, "error")
|
||||
.mockImplementation(() => {});
|
||||
onTestFinished(() => defaultError.mockRestore());
|
||||
const log = vi.fn();
|
||||
const configuredLogger = createLogger({ log });
|
||||
|
||||
await runWithEndpointContext(endpointContext(configuredLogger), () => {
|
||||
expect(safeJSONParse("{")).toBeNull();
|
||||
});
|
||||
|
||||
expect(log).toHaveBeenCalledWith(
|
||||
"error",
|
||||
"Error parsing JSON",
|
||||
expect.objectContaining({ error: expect.any(SyntaxError) }),
|
||||
);
|
||||
expect(defaultError).not.toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it("honors disabled logging in the current auth context", async () => {
|
||||
const defaultWarn = vi.spyOn(console, "warn").mockImplementation(() => {});
|
||||
onTestFinished(() => defaultWarn.mockRestore());
|
||||
const log = vi.fn();
|
||||
const configuredLogger = createLogger({ disabled: true, log });
|
||||
|
||||
await runWithEndpointContext(endpointContext(configuredLogger), () => {
|
||||
logger.warn("hidden warning");
|
||||
});
|
||||
|
||||
expect(log).not.toHaveBeenCalled();
|
||||
expect(defaultWarn).not.toHaveBeenCalled();
|
||||
});
|
||||
});
|
||||
|
||||
Vendored
+20
-1
@@ -1,3 +1,4 @@
|
||||
import { tryGetCurrentAuthContext } from "../context/endpoint-context";
|
||||
import { getColorDepth } from "./color-depth";
|
||||
|
||||
export const TTY_COLORS = {
|
||||
@@ -142,4 +143,22 @@ export const createLogger = (options?: Logger | undefined): InternalLogger => {
|
||||
};
|
||||
};
|
||||
|
||||
export const logger = createLogger();
|
||||
const defaultLogger = createLogger();
|
||||
|
||||
const getCurrentLogger = (): InternalLogger => {
|
||||
const currentLogger = tryGetCurrentAuthContext()?.context.logger;
|
||||
return currentLogger && currentLogger !== logger
|
||||
? currentLogger
|
||||
: defaultLogger;
|
||||
};
|
||||
|
||||
export const logger: InternalLogger = {
|
||||
debug: (...params) => getCurrentLogger().debug(...params),
|
||||
info: (...params) => getCurrentLogger().info(...params),
|
||||
success: (...params) => getCurrentLogger().success(...params),
|
||||
warn: (...params) => getCurrentLogger().warn(...params),
|
||||
error: (...params) => getCurrentLogger().error(...params),
|
||||
get level() {
|
||||
return getCurrentLogger().level;
|
||||
},
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user