more logging on slack oauth

This commit is contained in:
dal 2025-07-07 16:01:34 -06:00
parent 1a95c29673
commit e617eac67d
No known key found for this signature in database
GPG Key ID: 16F4B0E1E9F61122
2 changed files with 85 additions and 23 deletions

View File

@ -137,7 +137,7 @@ export class SlackHandler {
hasCode: !!query.code, hasCode: !!query.code,
hasState: !!query.state, hasState: !!query.state,
hasError: !!query.error, hasError: !!query.error,
paramCount: Object.keys(query).length paramCount: Object.keys(query).length,
}); });
const parsed = OAuthCallbackSchema.safeParse(query); const parsed = OAuthCallbackSchema.safeParse(query);
@ -151,7 +151,7 @@ export class SlackHandler {
console.error('Invalid OAuth callback parameters:', { console.error('Invalid OAuth callback parameters:', {
errors: parsed.error.errors, errors: parsed.error.errors,
providedKeys: Object.keys(query), providedKeys: Object.keys(query),
expectedKeys: ['code', 'state'] expectedKeys: ['code', 'state'],
}); });
return c.redirect('/settings/integrations?status=error&error=invalid_parameters'); return c.redirect('/settings/integrations?status=error&error=invalid_parameters');
} }
@ -167,7 +167,7 @@ export class SlackHandler {
console.error('OAuth callback failed:', { console.error('OAuth callback failed:', {
error: result.error, error: result.error,
hasError: !!result.error, hasError: !!result.error,
resultKeys: Object.keys(result) resultKeys: Object.keys(result),
}); });
const errorParam = encodeURIComponent(result.error || 'unknown_error'); const errorParam = encodeURIComponent(result.error || 'unknown_error');
return c.redirect(`/settings/integrations?status=error&error=${errorParam}`); return c.redirect(`/settings/integrations?status=error&error=${errorParam}`);
@ -185,7 +185,7 @@ export class SlackHandler {
errorType: error?.constructor?.name || 'Unknown', errorType: error?.constructor?.name || 'Unknown',
message: error instanceof Error ? error.message : 'Unknown error', message: error instanceof Error ? error.message : 'Unknown error',
isSlackError: error instanceof SlackError, 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'; const errorMessage = error instanceof Error ? error.message : 'callback_failed';
return c.redirect( return c.redirect(

View File

@ -46,7 +46,18 @@ export class SlackOAuthService {
oauthStateStorage oauthStateStorage
); );
} catch (error) { } 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( throw new Error(
`Failed to initialize Slack OAuth service: ${error instanceof Error ? error.message : 'Unknown error'}` `Failed to initialize Slack OAuth service: ${error instanceof Error ? error.message : 'Unknown error'}`
); );
@ -99,7 +110,15 @@ export class SlackOAuthService {
return { authUrl, state }; return { authUrl, state };
} catch (error) { } 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 throw error; // Re-throw to maintain existing error handling in handler
} }
} }
@ -165,11 +184,22 @@ export class SlackOAuthService {
teamName: tokenResponse.teamName, teamName: tokenResponse.teamName,
}; };
} catch (error) { } 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 // Try to get integration for cleanup
let integrationId = '';
try {
const integration = await slackHelpers.getPendingIntegrationByState(params.state); const integration = await slackHelpers.getPendingIntegrationByState(params.state);
if (integration) { if (integration) {
integrationId = integration.id;
await slackHelpers.markIntegrationAsFailed( await slackHelpers.markIntegrationAsFailed(
integration.id, integration.id,
error instanceof Error ? error.message : 'Unknown error' error instanceof Error ? error.message : 'Unknown error'
@ -180,10 +210,17 @@ export class SlackOAuthService {
error: error instanceof Error ? error.message : 'Unknown error occurred', 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 { return {
success: false, success: false,
integrationId: '', integrationId,
error: error instanceof Error ? error.message : 'Unknown error occurred', error: error instanceof Error ? error.message : 'Unknown error occurred',
}; };
} }
@ -243,7 +280,13 @@ export class SlackOAuthService {
}, },
}; };
} catch (error) { } 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; throw error;
} }
} }
@ -270,7 +313,14 @@ export class SlackOAuthService {
try { try {
await tokenStorage.deleteToken(integration.tokenVaultKey); await tokenStorage.deleteToken(integration.tokenVaultKey);
} catch (error) { } 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 // Continue with integration removal even if token deletion fails
} }
} }
@ -280,7 +330,13 @@ export class SlackOAuthService {
return { success: true }; return { success: true };
} catch (error) { } 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 { return {
success: false, success: false,
error: error instanceof Error ? error.message : 'Failed to remove integration', error: error instanceof Error ? error.message : 'Failed to remove integration',
@ -300,7 +356,13 @@ export class SlackOAuthService {
return await tokenStorage.getToken(integration.tokenVaultKey); return await tokenStorage.getToken(integration.tokenVaultKey);
} catch (error) { } 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; return null;
} }
} }