feat: remove console statements from SDK code

- Remove all console.log, console.warn, and console.error from src/client and src/server
- Add ESLint no-console rule for client and server directories (excluding tests)
- Keep console statements in test files, examples, and CLI tools as intended

Addresses feedback in PR #665

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
Ashwin Bhat 2025-06-19 22:34:13 -07:00
commit f4b8a48ded
No known key found for this signature in database
9 changed files with 31 additions and 28 deletions

View file

@ -15,5 +15,12 @@ export default tseslint.config(
{ "argsIgnorePattern": "^_" }
]
}
},
{
files: ["src/client/**/*.ts", "src/server/**/*.ts"],
ignores: ["**/*.test.ts"],
rules: {
"no-console": "error"
}
}
);

View file

@ -116,8 +116,8 @@ export async function auth(
if (resourceMetadata.authorization_servers && resourceMetadata.authorization_servers.length > 0) {
authorizationServerUrl = resourceMetadata.authorization_servers[0];
}
} catch (error) {
console.warn("Could not load OAuth Protected Resource metadata, falling back to /.well-known/oauth-authorization-server", error)
} catch {
// Ignore errors and fall back to /.well-known/oauth-authorization-server
}
const resource: URL | undefined = await selectResourceURL(serverUrl, provider, resourceMetadata);
@ -175,8 +175,8 @@ export async function auth(
await provider.saveTokens(newTokens);
return "AUTHORIZED";
} catch (error) {
console.error("Could not refresh OAuth tokens:", error);
} catch {
// Could not refresh OAuth tokens
}
}
@ -222,7 +222,6 @@ export function extractResourceMetadataUrl(res: Response): URL | undefined {
const [type, scheme] = authenticateHeader.split(' ');
if (type.toLowerCase() !== 'bearer' || !scheme) {
console.log("Invalid WWW-Authenticate header format, expected 'Bearer'");
return undefined;
}
const regex = /resource_metadata="([^"]*)"/;
@ -235,7 +234,6 @@ export function extractResourceMetadataUrl(res: Response): URL | undefined {
try {
return new URL(match[1]);
} catch {
console.log("Invalid resource metadata url: ", match[1]);
return undefined;
}
}

View file

@ -486,8 +486,8 @@ export class Client<
try {
const validator = this._ajv.compile(tool.outputSchema);
this._cachedToolOutputValidators.set(tool.name, validator);
} catch (error) {
console.warn(`Failed to compile output schema for tool ${tool.name}: ${error}`);
} catch {
// Ignore schema compilation errors
}
}
}

View file

@ -99,7 +99,6 @@ export function authorizationHandler({ provider, rateLimit: rateLimitConfig }: A
const status = error instanceof ServerError ? 500 : 400;
res.status(status).json(error.toResponseObject());
} else {
console.error("Unexpected error looking up client:", error);
const serverError = new ServerError("Internal Server Error");
res.status(500).json(serverError.toResponseObject());
}
@ -146,7 +145,6 @@ export function authorizationHandler({ provider, rateLimit: rateLimitConfig }: A
if (error instanceof OAuthError) {
res.redirect(302, createErrorRedirect(redirect_uri, error, state));
} else {
console.error("Unexpected error during authorization:", error);
const serverError = new ServerError("Internal Server Error");
res.redirect(302, createErrorRedirect(redirect_uri, serverError, state));
}

View file

@ -104,7 +104,6 @@ export function clientRegistrationHandler({
const status = error instanceof ServerError ? 500 : 400;
res.status(status).json(error.toResponseObject());
} else {
console.error("Unexpected error registering client:", error);
const serverError = new ServerError("Internal Server Error");
res.status(500).json(serverError.toResponseObject());
}

View file

@ -9,7 +9,7 @@ import {
InvalidRequestError,
ServerError,
TooManyRequestsError,
OAuthError
OAuthError,
} from "../errors.js";
export type RevocationHandlerOptions = {
@ -21,7 +21,10 @@ export type RevocationHandlerOptions = {
rateLimit?: Partial<RateLimitOptions> | false;
};
export function revocationHandler({ provider, rateLimit: rateLimitConfig }: RevocationHandlerOptions): RequestHandler {
export function revocationHandler({
provider,
rateLimit: rateLimitConfig,
}: RevocationHandlerOptions): RequestHandler {
if (!provider.revokeToken) {
throw new Error("Auth provider does not support revoking tokens");
}
@ -37,21 +40,25 @@ export function revocationHandler({ provider, rateLimit: rateLimitConfig }: Revo
// Apply rate limiting unless explicitly disabled
if (rateLimitConfig !== false) {
router.use(rateLimit({
windowMs: 15 * 60 * 1000, // 15 minutes
max: 50, // 50 requests per windowMs
standardHeaders: true,
legacyHeaders: false,
message: new TooManyRequestsError('You have exceeded the rate limit for token revocation requests').toResponseObject(),
...rateLimitConfig
}));
router.use(
rateLimit({
windowMs: 15 * 60 * 1000, // 15 minutes
max: 50, // 50 requests per windowMs
standardHeaders: true,
legacyHeaders: false,
message: new TooManyRequestsError(
"You have exceeded the rate limit for token revocation requests"
).toResponseObject(),
...rateLimitConfig,
})
);
}
// Authenticate and extract client details
router.use(authenticateClient({ clientsStore: provider.clientsStore }));
router.post("/", async (req, res) => {
res.setHeader('Cache-Control', 'no-store');
res.setHeader("Cache-Control", "no-store");
try {
const parseResult = OAuthTokenRevocationRequestSchema.safeParse(req.body);
@ -62,7 +69,6 @@ export function revocationHandler({ provider, rateLimit: rateLimitConfig }: Revo
const client = req.client;
if (!client) {
// This should never happen
console.error("Missing client information after authentication");
throw new ServerError("Internal Server Error");
}
@ -73,7 +79,6 @@ export function revocationHandler({ provider, rateLimit: rateLimitConfig }: Revo
const status = error instanceof ServerError ? 500 : 400;
res.status(status).json(error.toResponseObject());
} else {
console.error("Unexpected error revoking token:", error);
const serverError = new ServerError("Internal Server Error");
res.status(500).json(serverError.toResponseObject());
}

View file

@ -80,7 +80,6 @@ export function tokenHandler({ provider, rateLimit: rateLimitConfig }: TokenHand
const client = req.client;
if (!client) {
// This should never happen
console.error("Missing client information after authentication");
throw new ServerError("Internal Server Error");
}
@ -143,7 +142,6 @@ export function tokenHandler({ provider, rateLimit: rateLimitConfig }: TokenHand
const status = error instanceof ServerError ? 500 : 400;
res.status(status).json(error.toResponseObject());
} else {
console.error("Unexpected error exchanging token:", error);
const serverError = new ServerError("Internal Server Error");
res.status(500).json(serverError.toResponseObject());
}

View file

@ -88,7 +88,6 @@ export function requireBearerAuth({ verifier, requiredScopes = [], resourceMetad
} else if (error instanceof OAuthError) {
res.status(400).json(error.toResponseObject());
} else {
console.error("Unexpected error authenticating bearer token:", error);
const serverError = new ServerError("Internal Server Error");
res.status(500).json(serverError.toResponseObject());
}

View file

@ -64,7 +64,6 @@ export function authenticateClient({ clientsStore }: ClientAuthenticationMiddlew
const status = error instanceof ServerError ? 500 : 400;
res.status(status).json(error.toResponseObject());
} else {
console.error("Unexpected error authenticating client:", error);
const serverError = new ServerError("Internal Server Error");
res.status(500).json(serverError.toResponseObject());
}