or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

cli.mdconfig-api.mderrors.mdhigh-level-api.mdindex.mdprotocol.md

errors.mddocs/

0

# Error Handling

1

2

The `gntp.errors` module provides a comprehensive exception hierarchy for handling all GNTP-related error conditions. These exceptions are raised by all GNTP operations and provide detailed error information with appropriate error codes.

3

4

## Exception Hierarchy

5

6

All GNTP exceptions inherit from a common base class and include error codes that correspond to GNTP protocol error codes.

7

8

```python { .api }

9

class BaseError(Exception):

10

"""

11

Base exception class for all GNTP errors.

12

13

All GNTP exceptions inherit from this class.

14

"""

15

16

class ParseError(BaseError):

17

"""

18

Error parsing GNTP message.

19

20

Raised when GNTP message format is invalid, required headers are missing,

21

or message structure cannot be understood.

22

23

Attributes:

24

- errorcode (int): 500 (Internal Server Error)

25

- errordesc (str): 'Error parsing the message'

26

"""

27

28

class AuthError(BaseError):

29

"""

30

Error with GNTP authentication.

31

32

Raised when password is incorrect, missing when required, or hash

33

validation fails.

34

35

Attributes:

36

- errorcode (int): 400 (Bad Request)

37

- errordesc (str): 'Error with authorization'

38

"""

39

40

class UnsupportedError(BaseError):

41

"""

42

Currently unsupported operation or feature.

43

44

Raised when attempting to use unsupported hash algorithms, protocol

45

features, or operations not implemented in gntp.py.

46

47

Attributes:

48

- errorcode (int): 500 (Internal Server Error)

49

- errordesc (str): 'Currently unsupported by gntp.py'

50

"""

51

52

class NetworkError(BaseError):

53

"""

54

Error connecting to Growl server.

55

56

Raised when socket connection fails, server is unreachable, connection

57

times out, or other network-related issues occur.

58

59

Attributes:

60

- errorcode (int): 500 (Internal Server Error)

61

- errordesc (str): 'Error connecting to growl server'

62

"""

63

```

64

65

## Usage Examples

66

67

### Basic Error Handling

68

69

```python

70

import gntp.notifier

71

import gntp.errors

72

73

try:

74

growl = gntp.notifier.GrowlNotifier(hostname="unreachable-server.com")

75

growl.register()

76

growl.notify("Test", "Title", "Message")

77

78

except gntp.errors.NetworkError as e:

79

print(f"Cannot connect to Growl server: {e}")

80

print(f"Error code: {e.errorcode}")

81

82

except gntp.errors.AuthError as e:

83

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

84

print(f"Error code: {e.errorcode}")

85

86

except gntp.errors.ParseError as e:

87

print(f"Invalid response from server: {e}")

88

print(f"Error code: {e.errorcode}")

89

90

except gntp.errors.BaseError as e:

91

print(f"GNTP error: {e}")

92

print(f"Error code: {e.errorcode}")

93

```

94

95

### Specific Error Scenarios

96

97

#### Network Connectivity Issues

98

99

```python

100

import gntp.notifier

101

import gntp.errors

102

103

def send_notification_with_retry(message, max_retries=3):

104

for attempt in range(max_retries):

105

try:

106

growl = gntp.notifier.GrowlNotifier(

107

hostname="growl.company.com",

108

socketTimeout=5 # 5 second timeout

109

)

110

growl.register()

111

return growl.notify("Alert", "Status", message)

112

113

except gntp.errors.NetworkError as e:

114

print(f"Attempt {attempt + 1} failed: {e}")

115

if attempt == max_retries - 1:

116

print("All retry attempts failed")

117

raise

118

time.sleep(2 ** attempt) # Exponential backoff

119

```

120

121

#### Authentication Problems

122

123

```python

124

import gntp.notifier

125

import gntp.errors

126

127

def authenticate_with_fallback(app_name, message):

128

passwords = ["primary-password", "backup-password", None]

129

130

for password in passwords:

131

try:

132

growl = gntp.notifier.GrowlNotifier(

133

applicationName=app_name,

134

password=password

135

)

136

growl.register()

137

return growl.notify("Message", "Title", message)

138

139

except gntp.errors.AuthError:

140

if password is None:

141

print("All authentication methods failed")

142

raise

143

print(f"Password '{password}' failed, trying next...")

144

continue

145

```

146

147

#### Message Parsing Issues

148

149

```python

150

import gntp.core

151

import gntp.errors

152

153

def parse_server_response(raw_data):

154

try:

155

response = gntp.core.parse_gntp(raw_data)

156

return response

157

158

except gntp.errors.ParseError as e:

159

print(f"Cannot parse server response: {e}")

160

print(f"Raw data: {raw_data[:100]}...") # First 100 chars

161

162

# Try to extract any readable information

163

if b'GNTP/' in raw_data:

164

print("Response appears to be GNTP format but invalid")

165

else:

166

print("Response does not appear to be GNTP format")

167

168

raise

169

```

170

171

#### Unsupported Features

172

173

```python

174

import gntp.core

175

import gntp.errors

176

177

def create_secure_message(title, description):

178

try:

179

notice = gntp.core.GNTPNotice(title=title)

180

notice.add_header('Notification-Text', description)

181

182

# Try to use most secure hash algorithm

183

notice.set_password("secure-password", "SHA512")

184

return notice

185

186

except gntp.errors.UnsupportedError as e:

187

print(f"SHA512 not supported: {e}")

188

189

# Fall back to supported algorithm

190

notice.set_password("secure-password", "SHA256")

191

return notice

192

```

193

194

### Comprehensive Error Handling Strategy

195

196

```python

197

import gntp.notifier

198

import gntp.errors

199

import logging

200

201

class NotificationService:

202

def __init__(self, hostname="localhost", password=None):

203

self.hostname = hostname

204

self.password = password

205

self.logger = logging.getLogger(__name__)

206

207

def send_notification(self, title, message, priority=0):

208

"""Send notification with comprehensive error handling."""

209

210

try:

211

growl = gntp.notifier.GrowlNotifier(

212

applicationName="Notification Service",

213

notifications=["Alert", "Info", "Warning"],

214

hostname=self.hostname,

215

password=self.password

216

)

217

218

# Try to register

219

result = growl.register()

220

if result is not True:

221

self.logger.error(f"Registration failed: {result}")

222

return False

223

224

# Send notification

225

result = growl.notify("Alert", title, message, priority=priority)

226

if result is not True:

227

self.logger.error(f"Notification failed: {result}")

228

return False

229

230

self.logger.info("Notification sent successfully")

231

return True

232

233

except gntp.errors.NetworkError as e:

234

self.logger.error(f"Network error connecting to {self.hostname}: {e}")

235

return False

236

237

except gntp.errors.AuthError as e:

238

self.logger.error(f"Authentication failed: {e}")

239

return False

240

241

except gntp.errors.ParseError as e:

242

self.logger.error(f"Server response parsing failed: {e}")

243

return False

244

245

except gntp.errors.UnsupportedError as e:

246

self.logger.error(f"Unsupported operation: {e}")

247

return False

248

249

except gntp.errors.BaseError as e:

250

self.logger.error(f"Unexpected GNTP error: {e}")

251

return False

252

253

except Exception as e:

254

self.logger.error(f"Unexpected system error: {e}")

255

return False

256

257

# Usage

258

service = NotificationService("growl.company.com", "password123")

259

success = service.send_notification("Build Failed", "Unit tests failed", priority=2)

260

```

261

262

### Error Logging and Monitoring

263

264

```python

265

import gntp.notifier

266

import gntp.errors

267

import logging

268

import json

269

from datetime import datetime

270

271

def log_gntp_error(error, context=None):

272

"""Log GNTP errors with structured information."""

273

274

error_info = {

275

"timestamp": datetime.utcnow().isoformat(),

276

"error_type": type(error).__name__,

277

"error_code": getattr(error, 'errorcode', None),

278

"error_description": getattr(error, 'errordesc', None),

279

"error_message": str(error),

280

"context": context or {}

281

}

282

283

logging.error("GNTP Error: %s", json.dumps(error_info))

284

285

# Usage example

286

try:

287

gntp.notifier.mini("Test message", hostname="bad-server")

288

except gntp.errors.NetworkError as e:

289

log_gntp_error(e, {

290

"operation": "send_notification",

291

"hostname": "bad-server",

292

"message": "Test message"

293

})

294

```

295

296

## Error Recovery Patterns

297

298

### Graceful Degradation

299

300

```python

301

import gntp.notifier

302

import gntp.errors

303

import sys

304

305

def notify_with_fallback(message, title="Notification"):

306

"""Try Growl notification, fall back to console if it fails."""

307

308

try:

309

gntp.notifier.mini(message, title=title)

310

return "growl"

311

312

except gntp.errors.BaseError as e:

313

# Growl failed, fall back to console output

314

print(f"NOTIFICATION: {title} - {message}")

315

return "console"

316

```

317

318

### Circuit Breaker Pattern

319

320

```python

321

import gntp.notifier

322

import gntp.errors

323

import time

324

325

class GrowlCircuitBreaker:

326

def __init__(self, failure_threshold=5, timeout=60):

327

self.failure_threshold = failure_threshold

328

self.timeout = timeout

329

self.failure_count = 0

330

self.last_failure_time = None

331

self.state = "CLOSED" # CLOSED, OPEN, HALF_OPEN

332

333

def send_notification(self, message, **kwargs):

334

if self.state == "OPEN":

335

if time.time() - self.last_failure_time > self.timeout:

336

self.state = "HALF_OPEN"

337

else:

338

raise gntp.errors.NetworkError("Circuit breaker is OPEN")

339

340

try:

341

result = gntp.notifier.mini(message, **kwargs)

342

343

# Success - reset circuit breaker

344

self.failure_count = 0

345

self.state = "CLOSED"

346

return result

347

348

except gntp.errors.BaseError as e:

349

self.failure_count += 1

350

self.last_failure_time = time.time()

351

352

if self.failure_count >= self.failure_threshold:

353

self.state = "OPEN"

354

355

raise

356

```

357

358

## Error Codes Reference

359

360

| Exception | Error Code | Description | Common Causes |

361

|-----------|------------|-------------|---------------|

362

| `AuthError` | 400 | Bad Request | Wrong password, missing authentication |

363

| `ParseError` | 500 | Internal Server Error | Invalid message format, missing headers |

364

| `UnsupportedError` | 500 | Internal Server Error | Unsupported hash algorithm, unimplemented feature |

365

| `NetworkError` | 500 | Internal Server Error | Connection refused, timeout, network unreachable |

366

367

These error codes correspond to GNTP protocol error codes and can be used for protocol-level error handling and server implementation.