or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

authentication-flows.mddevice-code-flow.mdindex.mdlogging-error-handling.mdtoken-caching.md

logging-error-handling.mddocs/

0

# Logging and Error Handling

1

2

Comprehensive logging system with PII scrubbing capabilities and custom exception handling for authentication errors. ADAL provides detailed logging for debugging authentication issues while protecting sensitive information.

3

4

## Capabilities

5

6

### Logging Configuration

7

8

Configure the ADAL logger with custom log levels and handlers. The logging system supports correlation IDs for request tracking and PII scrubbing for security.

9

10

```python { .api }

11

def set_logging_options(options=None):

12

"""

13

Configure ADAL logger settings.

14

15

Parameters:

16

- options (dict, optional): Logging configuration with keys:

17

- 'level' (str): Log level ('DEBUG', 'INFO', 'WARNING', 'ERROR', 'CRITICAL')

18

- 'handler' (logging.Handler): Custom log handler instance

19

20

If options is None, resets to default logging configuration.

21

"""

22

```

23

24

**Usage Examples:**

25

26

```python

27

import adal

28

import logging

29

30

# Basic logging to console

31

adal.set_logging_options({

32

'level': 'DEBUG'

33

})

34

35

# Log to file with custom handler

36

adal.set_logging_options({

37

'level': 'INFO',

38

'handler': logging.FileHandler('adal.log')

39

})

40

41

# Custom formatting

42

handler = logging.StreamHandler()

43

formatter = logging.Formatter(

44

'%(asctime)s - %(name)s - %(levelname)s - %(message)s'

45

)

46

handler.setFormatter(formatter)

47

48

adal.set_logging_options({

49

'level': 'WARNING',

50

'handler': handler

51

})

52

53

# Reset to defaults

54

adal.set_logging_options()

55

```

56

57

### Get Current Logging Configuration

58

59

Retrieve the current logging configuration for inspection or backup.

60

61

```python { .api }

62

def get_logging_options():

63

"""

64

Get current logging configuration.

65

66

Returns:

67

dict: Current logging options with 'level' key

68

"""

69

```

70

71

**Usage Example:**

72

73

```python

74

# Save current configuration

75

current_config = adal.get_logging_options()

76

print(f"Current log level: {current_config['level']}")

77

78

# Temporarily change logging

79

adal.set_logging_options({'level': 'DEBUG'})

80

81

# Do some debugging work

82

context = adal.AuthenticationContext('https://login.microsoftonline.com/tenant-id')

83

# ... authentication calls with detailed logging

84

85

# Restore original configuration

86

adal.set_logging_options(current_config)

87

```

88

89

### ADAL Logger Name Constant

90

91

The standard logger name used by ADAL for all logging operations.

92

93

```python { .api }

94

ADAL_LOGGER_NAME: str # Value: "adal-python"

95

```

96

97

**Usage Example:**

98

99

```python

100

import logging

101

import adal

102

103

# Get the ADAL logger directly

104

adal_logger = logging.getLogger(adal.ADAL_LOGGER_NAME)

105

106

# Add custom handler to ADAL logger

107

custom_handler = logging.FileHandler('custom_adal.log')

108

custom_handler.setLevel(logging.INFO)

109

adal_logger.addHandler(custom_handler)

110

111

# Configure formatter

112

formatter = logging.Formatter(

113

'%(asctime)s [%(correlation_id)s] %(levelname)s: %(message)s'

114

)

115

custom_handler.setFormatter(formatter)

116

```

117

118

## Error Handling

119

120

### AdalError Exception

121

122

Custom exception class for ADAL-specific authentication and authorization errors. Provides detailed error information and optional response data.

123

124

```python { .api }

125

class AdalError(Exception):

126

def __init__(self, error_msg, error_response=None):

127

"""

128

ADAL-specific exception for authentication errors.

129

130

Parameters:

131

- error_msg (str): Human-readable error message

132

- error_response (dict, optional): Detailed error response from Azure AD

133

134

Attributes:

135

- error_response (dict): Azure AD error response details (if available)

136

"""

137

```

138

139

**Usage Examples:**

140

141

```python

142

import adal

143

144

context = adal.AuthenticationContext('https://login.microsoftonline.com/tenant-id')

145

146

try:

147

token = context.acquire_token_with_client_credentials(

148

resource='https://management.azure.com/',

149

client_id='invalid-client-id',

150

client_secret='invalid-secret'

151

)

152

except adal.AdalError as e:

153

print(f"Authentication failed: {e}")

154

155

# Check for detailed error response

156

if e.error_response:

157

print(f"Error code: {e.error_response.get('error')}")

158

print(f"Error description: {e.error_response.get('error_description')}")

159

print(f"Correlation ID: {e.error_response.get('correlation_id')}")

160

print(f"Timestamp: {e.error_response.get('timestamp')}")

161

```

162

163

### Common Error Scenarios

164

165

Handle different types of authentication errors appropriately:

166

167

```python

168

import adal

169

170

def robust_authentication():

171

context = adal.AuthenticationContext('https://login.microsoftonline.com/tenant-id')

172

173

try:

174

token = context.acquire_token_with_username_password(

175

resource='https://management.azure.com/',

176

username='user@tenant.com',

177

password='user-password',

178

client_id='your-client-id'

179

)

180

return token

181

182

except adal.AdalError as e:

183

error_msg = str(e).lower()

184

185

if 'invalid_client' in error_msg:

186

print("Error: Invalid client ID or client not configured properly")

187

188

elif 'invalid_grant' in error_msg:

189

print("Error: Invalid username/password or account disabled")

190

191

elif 'unauthorized_client' in error_msg:

192

print("Error: Client not authorized for this authentication flow")

193

194

elif 'invalid_resource' in error_msg:

195

print("Error: Invalid resource URI")

196

197

elif 'authority_not_found' in error_msg:

198

print("Error: Invalid tenant ID or authority URL")

199

200

elif 'network' in error_msg or 'timeout' in error_msg:

201

print("Error: Network connectivity issue")

202

203

else:

204

print(f"Unexpected authentication error: {e}")

205

206

# Log detailed error for debugging

207

if e.error_response:

208

print("Detailed error response:")

209

for key, value in e.error_response.items():

210

print(f" {key}: {value}")

211

212

return None

213

```

214

215

## Complete Logging Example

216

217

```python

218

import adal

219

import logging

220

import sys

221

from datetime import datetime

222

223

class AdalLoggingSetup:

224

def __init__(self, log_level='INFO', log_to_file=False, filename=None):

225

self.log_level = log_level

226

self.log_to_file = log_to_file

227

self.filename = filename or f'adal_{datetime.now().strftime("%Y%m%d_%H%M%S")}.log'

228

self.setup_logging()

229

230

def setup_logging(self):

231

"""Configure comprehensive ADAL logging"""

232

233

# Create custom handler

234

if self.log_to_file:

235

handler = logging.FileHandler(self.filename)

236

else:

237

handler = logging.StreamHandler(sys.stdout)

238

239

# Set log level

240

handler.setLevel(getattr(logging, self.log_level.upper()))

241

242

# Create detailed formatter

243

formatter = logging.Formatter(

244

'%(asctime)s - %(name)s - %(levelname)s - %(funcName)s:%(lineno)d - %(message)s'

245

)

246

handler.setFormatter(formatter)

247

248

# Configure ADAL logging

249

adal.set_logging_options({

250

'level': self.log_level,

251

'handler': handler

252

})

253

254

print(f"ADAL logging configured: level={self.log_level}, file={self.filename if self.log_to_file else 'console'}")

255

256

def demo_with_logging():

257

# Setup comprehensive logging

258

logging_setup = AdalLoggingSetup(

259

log_level='DEBUG',

260

log_to_file=True,

261

filename='adal_debug.log'

262

)

263

264

# Create authentication context

265

authority = 'https://login.microsoftonline.com/your-tenant-id'

266

context = adal.AuthenticationContext(authority)

267

268

try:

269

# This will generate detailed debug logs

270

print("Attempting authentication...")

271

token = context.acquire_token_with_client_credentials(

272

resource='https://management.azure.com/',

273

client_id='your-client-id',

274

client_secret='your-client-secret'

275

)

276

277

print("Authentication successful!")

278

print(f"Token type: {token.get('tokenType')}")

279

print(f"Expires on: {token.get('expiresOn')}")

280

281

except adal.AdalError as e:

282

print(f"Authentication failed: {e}")

283

284

# Log error details

285

adal_logger = logging.getLogger(adal.ADAL_LOGGER_NAME)

286

adal_logger.error(f"Authentication error: {e}")

287

288

if e.error_response:

289

adal_logger.error(f"Error response: {e.error_response}")

290

291

# Show current logging configuration

292

config = adal.get_logging_options()

293

print(f"Final logging configuration: {config}")

294

295

if __name__ == '__main__':

296

demo_with_logging()

297

```

298

299

## PII Protection

300

301

ADAL automatically scrubs personally identifiable information (PII) from logs when PII logging is disabled (default). When creating an AuthenticationContext, you can control PII logging:

302

303

```python

304

# PII scrubbing enabled (default)

305

context = adal.AuthenticationContext(

306

'https://login.microsoftonline.com/tenant-id',

307

enable_pii=False

308

)

309

310

# PII logging enabled (for debugging only)

311

context = adal.AuthenticationContext(

312

'https://login.microsoftonline.com/tenant-id',

313

enable_pii=True

314

)

315

```

316

317

**Important**: Only enable PII logging in secure development environments. Never enable PII logging in production systems.

318

319

## Best Practices

320

321

1. **Use appropriate log levels**: DEBUG for development, INFO for production monitoring

322

2. **Secure log files**: Ensure log files have appropriate permissions and are stored securely

323

3. **Rotate logs**: Implement log rotation to prevent disk space issues

324

4. **Monitor errors**: Set up alerts for authentication failures in production

325

5. **Correlation IDs**: Use correlation IDs to track requests across systems

326

6. **PII protection**: Keep PII scrubbing enabled in production environments