From e617eac67dfbd4c0f26a6f72eb1acb90ef20a233 Mon Sep 17 00:00:00 2001 From: dal Date: Mon, 7 Jul 2025 16:01:34 -0600 Subject: [PATCH] more logging on slack oauth --- apps/server/src/api/v2/slack/handler.ts | 8 +- .../v2/slack/services/slack-oauth-service.ts | 100 ++++++++++++++---- 2 files changed, 85 insertions(+), 23 deletions(-) diff --git a/apps/server/src/api/v2/slack/handler.ts b/apps/server/src/api/v2/slack/handler.ts index 5a47eeec9..dae50c5a5 100644 --- a/apps/server/src/api/v2/slack/handler.ts +++ b/apps/server/src/api/v2/slack/handler.ts @@ -137,7 +137,7 @@ export class SlackHandler { hasCode: !!query.code, hasState: !!query.state, hasError: !!query.error, - paramCount: Object.keys(query).length + paramCount: Object.keys(query).length, }); const parsed = OAuthCallbackSchema.safeParse(query); @@ -151,7 +151,7 @@ export class SlackHandler { console.error('Invalid OAuth callback parameters:', { errors: parsed.error.errors, providedKeys: Object.keys(query), - expectedKeys: ['code', 'state'] + expectedKeys: ['code', 'state'], }); return c.redirect('/settings/integrations?status=error&error=invalid_parameters'); } @@ -167,7 +167,7 @@ export class SlackHandler { console.error('OAuth callback failed:', { error: result.error, hasError: !!result.error, - resultKeys: Object.keys(result) + resultKeys: Object.keys(result), }); const errorParam = encodeURIComponent(result.error || 'unknown_error'); return c.redirect(`/settings/integrations?status=error&error=${errorParam}`); @@ -185,7 +185,7 @@ export class SlackHandler { errorType: error?.constructor?.name || 'Unknown', message: error instanceof Error ? error.message : 'Unknown error', isSlackError: error instanceof SlackError, - hasStack: !!(error instanceof Error && error.stack) + hasStack: !!(error instanceof Error && error.stack), }); const errorMessage = error instanceof Error ? error.message : 'callback_failed'; return c.redirect( diff --git a/apps/server/src/api/v2/slack/services/slack-oauth-service.ts b/apps/server/src/api/v2/slack/services/slack-oauth-service.ts index 003e8c371..4baa1731e 100644 --- a/apps/server/src/api/v2/slack/services/slack-oauth-service.ts +++ b/apps/server/src/api/v2/slack/services/slack-oauth-service.ts @@ -46,7 +46,18 @@ export class SlackOAuthService { oauthStateStorage ); } catch (error) { - console.error('Failed to initialize SlackOAuthService:', error); + console.error('Failed to initialize SlackOAuthService:', { + error: error instanceof Error ? error.message : String(error), + stack: error instanceof Error ? error.stack : undefined, + errorType: error instanceof Error ? error.constructor.name : typeof error, + timestamp: new Date().toISOString(), + environment: { + hasClientId: !!process.env.SLACK_CLIENT_ID, + hasClientSecret: !!process.env.SLACK_CLIENT_SECRET, + hasRedirectUri: !!process.env.SLACK_REDIRECT_URI, + integrationEnabled: process.env.SLACK_INTEGRATION_ENABLED, + }, + }); throw new Error( `Failed to initialize Slack OAuth service: ${error instanceof Error ? error.message : 'Unknown error'}` ); @@ -99,7 +110,15 @@ export class SlackOAuthService { return { authUrl, state }; } catch (error) { - console.error('Failed to initiate OAuth:', error); + console.error('Failed to initiate OAuth:', { + error: error instanceof Error ? error.message : String(error), + stack: error instanceof Error ? error.stack : undefined, + organizationId: params.organizationId, + userId: params.userId, + errorType: error instanceof Error ? error.constructor.name : typeof error, + timestamp: new Date().toISOString(), + integrationEnabled: this.isEnabled(), + }); throw error; // Re-throw to maintain existing error handling in handler } } @@ -165,25 +184,43 @@ export class SlackOAuthService { teamName: tokenResponse.teamName, }; } catch (error) { - console.error('OAuth callback error:', error); + // Enhanced error logging with structured data + console.error('OAuth callback error:', { + error: error instanceof Error ? error.message : String(error), + stack: error instanceof Error ? error.stack : undefined, + code: params.code ? '[REDACTED]' : 'missing', // Don't log sensitive data + state: params.state ? `${params.state.substring(0, 8)}...` : 'missing', // Partial state for debugging + errorType: error instanceof Error ? error.constructor.name : typeof error, + timestamp: new Date().toISOString(), + }); // Try to get integration for cleanup - const integration = await slackHelpers.getPendingIntegrationByState(params.state); - if (integration) { - await slackHelpers.markIntegrationAsFailed( - integration.id, - error instanceof Error ? error.message : 'Unknown error' - ); - return { - success: false, - integrationId: integration.id, - error: error instanceof Error ? error.message : 'Unknown error occurred', - }; + let integrationId = ''; + try { + const integration = await slackHelpers.getPendingIntegrationByState(params.state); + if (integration) { + integrationId = integration.id; + await slackHelpers.markIntegrationAsFailed( + integration.id, + error instanceof Error ? error.message : 'Unknown error' + ); + return { + success: false, + integrationId: integration.id, + error: error instanceof Error ? error.message : 'Unknown error occurred', + }; + } + } catch (cleanupError) { + console.error('Failed to cleanup after OAuth error:', { + originalError: error instanceof Error ? error.message : String(error), + cleanupError: cleanupError instanceof Error ? cleanupError.message : String(cleanupError), + state: params.state ? `${params.state.substring(0, 8)}...` : 'missing', + }); } return { success: false, - integrationId: '', + integrationId, error: error instanceof Error ? error.message : 'Unknown error occurred', }; } @@ -243,7 +280,13 @@ export class SlackOAuthService { }, }; } catch (error) { - console.error('Failed to get integration status:', error); + console.error('Failed to get integration status:', { + error: error instanceof Error ? error.message : String(error), + stack: error instanceof Error ? error.stack : undefined, + organizationId, + errorType: error instanceof Error ? error.constructor.name : typeof error, + timestamp: new Date().toISOString(), + }); throw error; } } @@ -270,7 +313,14 @@ export class SlackOAuthService { try { await tokenStorage.deleteToken(integration.tokenVaultKey); } catch (error) { - console.error('Failed to delete token from vault:', error); + console.error('Failed to delete token from vault:', { + error: error instanceof Error ? error.message : String(error), + stack: error instanceof Error ? error.stack : undefined, + tokenVaultKey: integration.tokenVaultKey, + integrationId: integration.id, + errorType: error instanceof Error ? error.constructor.name : typeof error, + timestamp: new Date().toISOString(), + }); // Continue with integration removal even if token deletion fails } } @@ -280,7 +330,13 @@ export class SlackOAuthService { return { success: true }; } catch (error) { - console.error('Failed to remove integration:', error); + console.error('Failed to remove integration:', { + error: error instanceof Error ? error.message : String(error), + stack: error instanceof Error ? error.stack : undefined, + organizationId, + errorType: error instanceof Error ? error.constructor.name : typeof error, + timestamp: new Date().toISOString(), + }); return { success: false, error: error instanceof Error ? error.message : 'Failed to remove integration', @@ -300,7 +356,13 @@ export class SlackOAuthService { return await tokenStorage.getToken(integration.tokenVaultKey); } catch (error) { - console.error('Failed to get token from vault:', error); + console.error('Failed to get token from vault:', { + error: error instanceof Error ? error.message : String(error), + stack: error instanceof Error ? error.stack : undefined, + integrationId, + errorType: error instanceof Error ? error.constructor.name : typeof error, + timestamp: new Date().toISOString(), + }); return null; } }