0
# Error Handling
1
2
Comprehensive error types with specific codes for different OAuth failure scenarios, enabling precise error handling and debugging.
3
4
## Capabilities
5
6
### Error Base Types
7
8
Base interfaces and enums for OAuth error handling.
9
10
```typescript { .api }
11
/**
12
* Base interface for errors with specific error codes
13
*/
14
interface CodedError extends Error {
15
/** Error code identifying the specific error type */
16
code: string;
17
}
18
19
/**
20
* Enumeration of OAuth-specific error codes
21
*/
22
enum ErrorCode {
23
/** Error during InstallProvider initialization */
24
InstallerInitializationError = "slack_oauth_installer_initialization_error";
25
/** Error during authorization/authentication */
26
AuthorizationError = "slack_oauth_installer_authorization_error";
27
/** Error generating OAuth installation URL */
28
GenerateInstallUrlError = "slack_oauth_generate_url_error";
29
/** Missing required state parameter */
30
MissingStateError = "slack_oauth_missing_state";
31
/** Invalid or corrupted state parameter */
32
InvalidStateError = "slack_oauth_invalid_state";
33
/** Missing required authorization code */
34
MissingCodeError = "slack_oauth_missing_code";
35
/** Unexpected or unhandled error */
36
UnknownError = "slack_oauth_unknown_error";
37
}
38
```
39
40
### Specific Error Classes
41
42
Individual error classes for different OAuth failure scenarios.
43
44
#### InstallerInitializationError
45
46
```typescript { .api }
47
/**
48
* Error thrown during InstallProvider initialization
49
* Common causes: missing client ID/secret, invalid configuration
50
*/
51
class InstallerInitializationError extends Error implements CodedError {
52
public code = ErrorCode.InstallerInitializationError;
53
54
constructor(message: string);
55
}
56
```
57
58
#### AuthorizationError
59
60
```typescript { .api }
61
/**
62
* Error during authorization process with optional wrapped original error
63
*/
64
class AuthorizationError extends Error implements CodedError {
65
public code = ErrorCode.AuthorizationError;
66
/** Original error that caused this authorization failure */
67
public original?: Error;
68
69
/**
70
* @param message - Error description
71
* @param original - Optional original error that caused this failure
72
*/
73
constructor(message: string, original?: Error);
74
}
75
```
76
77
#### GenerateInstallUrlError
78
79
```typescript { .api }
80
/**
81
* Error when generating OAuth installation URL
82
* Common causes: invalid options, missing configuration
83
*/
84
class GenerateInstallUrlError extends Error implements CodedError {
85
public code = ErrorCode.GenerateInstallUrlError;
86
87
constructor(message: string);
88
}
89
```
90
91
#### State Parameter Errors
92
93
```typescript { .api }
94
/**
95
* Error when state parameter is missing from OAuth callback
96
*/
97
class MissingStateError extends Error implements CodedError {
98
public code = ErrorCode.MissingStateError;
99
100
constructor(message: string);
101
}
102
103
/**
104
* Error when state parameter is invalid, corrupted, or expired
105
*/
106
class InvalidStateError extends Error implements CodedError {
107
public code = ErrorCode.InvalidStateError;
108
109
constructor(message: string);
110
}
111
```
112
113
#### Authorization Code Errors
114
115
```typescript { .api }
116
/**
117
* Error when authorization code is missing from OAuth callback
118
*/
119
class MissingCodeError extends Error implements CodedError {
120
public code = ErrorCode.MissingCodeError;
121
122
constructor(message: string);
123
}
124
```
125
126
#### Generic Error
127
128
```typescript { .api }
129
/**
130
* Generic error for unexpected OAuth failures
131
*/
132
class UnknownError extends Error implements CodedError {
133
public code = ErrorCode.UnknownError;
134
135
constructor(message: string);
136
}
137
```
138
139
**Usage Examples:**
140
141
```typescript
142
import {
143
InstallProvider,
144
ErrorCode,
145
InstallerInitializationError,
146
AuthorizationError,
147
GenerateInstallUrlError,
148
MissingStateError,
149
InvalidStateError,
150
MissingCodeError,
151
UnknownError,
152
CodedError
153
} from "@slack/oauth";
154
155
// Error handling during initialization
156
try {
157
const installer = new InstallProvider({
158
clientId: "", // Invalid: empty client ID
159
clientSecret: process.env.SLACK_CLIENT_SECRET!,
160
stateSecret: "secret",
161
});
162
} catch (error) {
163
if (error instanceof InstallerInitializationError) {
164
console.error("Initialization error:", error.message);
165
console.error("Error code:", error.code);
166
}
167
}
168
169
// Error handling during URL generation
170
try {
171
const installer = new InstallProvider({
172
clientId: process.env.SLACK_CLIENT_ID!,
173
clientSecret: process.env.SLACK_CLIENT_SECRET!,
174
stateSecret: "secret",
175
});
176
177
const url = await installer.generateInstallUrl({
178
scopes: [], // Invalid: empty scopes
179
});
180
} catch (error) {
181
if (error instanceof GenerateInstallUrlError) {
182
console.error("URL generation failed:", error.message);
183
}
184
}
185
186
// Error handling during authorization
187
try {
188
const authResult = await installer.authorize({
189
teamId: "INVALID_TEAM_ID",
190
});
191
} catch (error) {
192
if (error instanceof AuthorizationError) {
193
console.error("Authorization failed:", error.message);
194
if (error.original) {
195
console.error("Original error:", error.original.message);
196
}
197
}
198
}
199
200
// Comprehensive error handling in callback handler
201
app.get("/slack/oauth_redirect", async (req, res) => {
202
try {
203
await installer.handleCallback(req, res);
204
} catch (error) {
205
// Type-safe error handling
206
if (error instanceof MissingStateError) {
207
console.error("State parameter missing from callback");
208
res.status(400).send("Invalid OAuth request: missing state");
209
} else if (error instanceof InvalidStateError) {
210
console.error("State parameter invalid or expired");
211
res.status(400).send("Invalid OAuth request: invalid state");
212
} else if (error instanceof MissingCodeError) {
213
console.error("Authorization code missing from callback");
214
res.status(400).send("Invalid OAuth request: missing code");
215
} else if (error instanceof AuthorizationError) {
216
console.error("Authorization failed:", error.message);
217
res.status(500).send("OAuth authorization failed");
218
} else {
219
console.error("Unknown OAuth error:", error);
220
res.status(500).send("OAuth request failed");
221
}
222
}
223
});
224
225
// Generic error code checking
226
function handleOAuthError(error: unknown) {
227
if (error && typeof error === "object" && "code" in error) {
228
const codedError = error as CodedError;
229
230
switch (codedError.code) {
231
case ErrorCode.InstallerInitializationError:
232
console.log("Fix your InstallProvider configuration");
233
break;
234
case ErrorCode.AuthorizationError:
235
console.log("Check your app credentials and permissions");
236
break;
237
case ErrorCode.GenerateInstallUrlError:
238
console.log("Verify your OAuth URL options");
239
break;
240
case ErrorCode.MissingStateError:
241
case ErrorCode.InvalidStateError:
242
console.log("State parameter issue - possible CSRF attack");
243
break;
244
case ErrorCode.MissingCodeError:
245
console.log("Authorization code missing - user may have denied access");
246
break;
247
case ErrorCode.UnknownError:
248
default:
249
console.log("Unexpected OAuth error occurred");
250
break;
251
}
252
}
253
}
254
255
// Error handling with custom callback handlers
256
const installer = new InstallProvider({
257
clientId: process.env.SLACK_CLIENT_ID!,
258
clientSecret: process.env.SLACK_CLIENT_SECRET!,
259
stateSecret: "secret",
260
});
261
262
app.get("/slack/oauth_redirect", async (req, res) => {
263
await installer.handleCallback(req, res, {
264
success: (installation, options, req, res) => {
265
console.log("OAuth successful for team:", installation.team?.id);
266
res.send("Installation successful!");
267
},
268
failure: (error, options, req, res) => {
269
console.error("OAuth failed:", error.code, error.message);
270
271
// Custom error responses based on error type
272
if (error.code === ErrorCode.InvalidStateError) {
273
res.status(400).send("Security error: Invalid request state");
274
} else if (error.code === ErrorCode.AuthorizationError) {
275
res.status(401).send("Authorization failed");
276
} else {
277
res.status(500).send("Installation failed");
278
}
279
},
280
});
281
});
282
```