or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

error-handling.mdindex.mdinstallation-storage.mdoauth-flow.mdstate-management.md

error-handling.mddocs/

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

```