Official library for interacting with Slack's OAuth endpoints
—
Comprehensive error types with specific codes for different OAuth failure scenarios, enabling precise error handling and debugging.
Base interfaces and enums for OAuth error handling.
/**
* Base interface for errors with specific error codes
*/
interface CodedError extends Error {
/** Error code identifying the specific error type */
code: string;
}
/**
* Enumeration of OAuth-specific error codes
*/
enum ErrorCode {
/** Error during InstallProvider initialization */
InstallerInitializationError = "slack_oauth_installer_initialization_error";
/** Error during authorization/authentication */
AuthorizationError = "slack_oauth_installer_authorization_error";
/** Error generating OAuth installation URL */
GenerateInstallUrlError = "slack_oauth_generate_url_error";
/** Missing required state parameter */
MissingStateError = "slack_oauth_missing_state";
/** Invalid or corrupted state parameter */
InvalidStateError = "slack_oauth_invalid_state";
/** Missing required authorization code */
MissingCodeError = "slack_oauth_missing_code";
/** Unexpected or unhandled error */
UnknownError = "slack_oauth_unknown_error";
}Individual error classes for different OAuth failure scenarios.
/**
* Error thrown during InstallProvider initialization
* Common causes: missing client ID/secret, invalid configuration
*/
class InstallerInitializationError extends Error implements CodedError {
public code = ErrorCode.InstallerInitializationError;
constructor(message: string);
}/**
* Error during authorization process with optional wrapped original error
*/
class AuthorizationError extends Error implements CodedError {
public code = ErrorCode.AuthorizationError;
/** Original error that caused this authorization failure */
public original?: Error;
/**
* @param message - Error description
* @param original - Optional original error that caused this failure
*/
constructor(message: string, original?: Error);
}/**
* Error when generating OAuth installation URL
* Common causes: invalid options, missing configuration
*/
class GenerateInstallUrlError extends Error implements CodedError {
public code = ErrorCode.GenerateInstallUrlError;
constructor(message: string);
}/**
* Error when state parameter is missing from OAuth callback
*/
class MissingStateError extends Error implements CodedError {
public code = ErrorCode.MissingStateError;
constructor(message: string);
}
/**
* Error when state parameter is invalid, corrupted, or expired
*/
class InvalidStateError extends Error implements CodedError {
public code = ErrorCode.InvalidStateError;
constructor(message: string);
}/**
* Error when authorization code is missing from OAuth callback
*/
class MissingCodeError extends Error implements CodedError {
public code = ErrorCode.MissingCodeError;
constructor(message: string);
}/**
* Generic error for unexpected OAuth failures
*/
class UnknownError extends Error implements CodedError {
public code = ErrorCode.UnknownError;
constructor(message: string);
}Usage Examples:
import {
InstallProvider,
ErrorCode,
InstallerInitializationError,
AuthorizationError,
GenerateInstallUrlError,
MissingStateError,
InvalidStateError,
MissingCodeError,
UnknownError,
CodedError
} from "@slack/oauth";
// Error handling during initialization
try {
const installer = new InstallProvider({
clientId: "", // Invalid: empty client ID
clientSecret: process.env.SLACK_CLIENT_SECRET!,
stateSecret: "secret",
});
} catch (error) {
if (error instanceof InstallerInitializationError) {
console.error("Initialization error:", error.message);
console.error("Error code:", error.code);
}
}
// Error handling during URL generation
try {
const installer = new InstallProvider({
clientId: process.env.SLACK_CLIENT_ID!,
clientSecret: process.env.SLACK_CLIENT_SECRET!,
stateSecret: "secret",
});
const url = await installer.generateInstallUrl({
scopes: [], // Invalid: empty scopes
});
} catch (error) {
if (error instanceof GenerateInstallUrlError) {
console.error("URL generation failed:", error.message);
}
}
// Error handling during authorization
try {
const authResult = await installer.authorize({
teamId: "INVALID_TEAM_ID",
});
} catch (error) {
if (error instanceof AuthorizationError) {
console.error("Authorization failed:", error.message);
if (error.original) {
console.error("Original error:", error.original.message);
}
}
}
// Comprehensive error handling in callback handler
app.get("/slack/oauth_redirect", async (req, res) => {
try {
await installer.handleCallback(req, res);
} catch (error) {
// Type-safe error handling
if (error instanceof MissingStateError) {
console.error("State parameter missing from callback");
res.status(400).send("Invalid OAuth request: missing state");
} else if (error instanceof InvalidStateError) {
console.error("State parameter invalid or expired");
res.status(400).send("Invalid OAuth request: invalid state");
} else if (error instanceof MissingCodeError) {
console.error("Authorization code missing from callback");
res.status(400).send("Invalid OAuth request: missing code");
} else if (error instanceof AuthorizationError) {
console.error("Authorization failed:", error.message);
res.status(500).send("OAuth authorization failed");
} else {
console.error("Unknown OAuth error:", error);
res.status(500).send("OAuth request failed");
}
}
});
// Generic error code checking
function handleOAuthError(error: unknown) {
if (error && typeof error === "object" && "code" in error) {
const codedError = error as CodedError;
switch (codedError.code) {
case ErrorCode.InstallerInitializationError:
console.log("Fix your InstallProvider configuration");
break;
case ErrorCode.AuthorizationError:
console.log("Check your app credentials and permissions");
break;
case ErrorCode.GenerateInstallUrlError:
console.log("Verify your OAuth URL options");
break;
case ErrorCode.MissingStateError:
case ErrorCode.InvalidStateError:
console.log("State parameter issue - possible CSRF attack");
break;
case ErrorCode.MissingCodeError:
console.log("Authorization code missing - user may have denied access");
break;
case ErrorCode.UnknownError:
default:
console.log("Unexpected OAuth error occurred");
break;
}
}
}
// Error handling with custom callback handlers
const installer = new InstallProvider({
clientId: process.env.SLACK_CLIENT_ID!,
clientSecret: process.env.SLACK_CLIENT_SECRET!,
stateSecret: "secret",
});
app.get("/slack/oauth_redirect", async (req, res) => {
await installer.handleCallback(req, res, {
success: (installation, options, req, res) => {
console.log("OAuth successful for team:", installation.team?.id);
res.send("Installation successful!");
},
failure: (error, options, req, res) => {
console.error("OAuth failed:", error.code, error.message);
// Custom error responses based on error type
if (error.code === ErrorCode.InvalidStateError) {
res.status(400).send("Security error: Invalid request state");
} else if (error.code === ErrorCode.AuthorizationError) {
res.status(401).send("Authorization failed");
} else {
res.status(500).send("Installation failed");
}
},
});
});Install with Tessl CLI
npx tessl i tessl/npm-slack--oauth