or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

core-processing.mderrors.mdfiltering.mdindex.mdtheming.md

errors.mddocs/

0

# Error Handling

1

2

Exception classes for handling parsing errors that can occur when processing Eliot message dictionaries and JSON text. These exceptions provide detailed error context and debugging information to help identify and resolve issues with malformed or invalid log data.

3

4

## Capabilities

5

6

### Eliot Parse Error Handling

7

8

Exception raised when parsing fails for Eliot message dictionaries during task processing.

9

10

```python { .api }

11

class EliotParseError(RuntimeError):

12

"""

13

An error occurred while parsing a particular Eliot message dictionary.

14

15

Attributes:

16

- message_dict: dict - The problematic Eliot message dictionary that caused the error

17

- exc_info: tuple - Exception information tuple from sys.exc_info()

18

"""

19

20

def __init__(self, message_dict, exc_info):

21

"""

22

Initialize EliotParseError with context information.

23

24

Parameters:

25

- message_dict: dict - The Eliot message dictionary that failed to parse

26

- exc_info: tuple - Exception information from sys.exc_info()

27

"""

28

```

29

30

**Usage Example:**

31

32

```python

33

from eliottree import tasks_from_iterable, EliotParseError

34

import sys

35

36

def safe_task_parsing(messages):

37

"""Parse tasks with error handling."""

38

try:

39

tasks = list(tasks_from_iterable(messages))

40

return tasks

41

except EliotParseError as e:

42

print(f"Failed to parse Eliot message: {e.message_dict}")

43

print(f"Original exception: {e.exc_info[1]}")

44

45

# Log full exception details

46

import traceback

47

traceback.print_exception(*e.exc_info)

48

49

return []

50

51

# Usage with potentially malformed messages

52

messages = [

53

{"timestamp": 1425356936.278875, "action_status": "started"}, # Missing required fields

54

{"task_uuid": "invalid", "malformed": True} # Invalid structure

55

]

56

57

tasks = safe_task_parsing(messages)

58

```

59

60

### JSON Parse Error Handling

61

62

Exception raised when JSON parsing fails during file processing, providing context about the specific location and content of the parsing failure.

63

64

```python { .api }

65

class JSONParseError(RuntimeError):

66

"""

67

An error occurred while parsing JSON text from a file or input stream.

68

69

Attributes:

70

- file_name: str - Name of the file being parsed when error occurred

71

- line_number: int - Line number in the file where parsing failed

72

- line: str - The actual line content that caused the parsing error

73

- exc_info: tuple - Exception information tuple from sys.exc_info()

74

"""

75

76

def __init__(self, file_name, line_number, line, exc_info):

77

"""

78

Initialize JSONParseError with detailed context.

79

80

Parameters:

81

- file_name: str - Name of the file being parsed

82

- line_number: int - Line number where error occurred

83

- line: str - Content of the problematic line

84

- exc_info: tuple - Exception information from sys.exc_info()

85

"""

86

```

87

88

**Usage Example:**

89

90

```python

91

import json

92

from eliottree import JSONParseError

93

94

def parse_eliot_log_file(file_path):

95

"""Parse Eliot log file with comprehensive error handling."""

96

messages = []

97

98

try:

99

with open(file_path, 'r') as f:

100

for line_num, line in enumerate(f, 1):

101

line = line.strip()

102

if not line:

103

continue

104

105

try:

106

message = json.loads(line)

107

messages.append(message)

108

except json.JSONDecodeError as e:

109

# Wrap in JSONParseError with context

110

import sys

111

raise JSONParseError(

112

file_name=file_path,

113

line_number=line_num,

114

line=line,

115

exc_info=sys.exc_info()

116

)

117

118

except JSONParseError as e:

119

print(f"JSON parsing failed in {e.file_name} at line {e.line_number}")

120

print(f"Problematic line: {e.line}")

121

print(f"JSON error: {e.exc_info[1]}")

122

return []

123

124

except IOError as e:

125

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

126

return []

127

128

return messages

129

130

# Usage

131

messages = parse_eliot_log_file('eliot.log')

132

```

133

134

## Complete Error Handling Pipeline

135

136

```python

137

import json

138

import sys

139

from eliottree import (

140

tasks_from_iterable, render_tasks, get_theme,

141

EliotParseError, JSONParseError

142

)

143

144

def robust_eliot_processing(file_path):

145

"""

146

Complete error-handling pipeline for Eliot log processing.

147

"""

148

149

def parse_json_file(file_path):

150

"""Parse JSON file with line-by-line error handling."""

151

messages = []

152

errors = []

153

154

try:

155

with open(file_path, 'r') as f:

156

for line_num, line in enumerate(f, 1):

157

line = line.strip()

158

if not line:

159

continue

160

161

try:

162

message = json.loads(line)

163

messages.append(message)

164

except json.JSONDecodeError as json_err:

165

error = {

166

'type': 'JSON',

167

'line_number': line_num,

168

'line': line,

169

'error': str(json_err)

170

}

171

errors.append(error)

172

continue

173

174

except IOError as io_err:

175

print(f"Cannot read file {file_path}: {io_err}")

176

return [], []

177

178

return messages, errors

179

180

def parse_eliot_tasks(messages):

181

"""Parse Eliot tasks with error collection."""

182

tasks = []

183

errors = []

184

185

try:

186

for task in tasks_from_iterable(messages):

187

tasks.append(task)

188

except EliotParseError as e:

189

error = {

190

'type': 'Eliot',

191

'message_dict': e.message_dict,

192

'error': str(e.exc_info[1])

193

}

194

errors.append(error)

195

196

return tasks, errors

197

198

# Main processing

199

print(f"Processing {file_path}...")

200

201

# Parse JSON

202

messages, json_errors = parse_json_file(file_path)

203

204

if json_errors:

205

print(f"JSON parsing errors: {len(json_errors)}")

206

for error in json_errors[:5]: # Show first 5 errors

207

print(f" Line {error['line_number']}: {error['error']}")

208

209

if not messages:

210

print("No valid messages found")

211

return

212

213

# Parse Eliot tasks

214

tasks, eliot_errors = parse_eliot_tasks(messages)

215

216

if eliot_errors:

217

print(f"Eliot parsing errors: {len(eliot_errors)}")

218

for error in eliot_errors[:3]: # Show first 3 errors

219

print(f" Message: {error['message_dict']}")

220

print(f" Error: {error['error']}")

221

222

if not tasks:

223

print("No valid tasks generated")

224

return

225

226

# Render with error handling

227

def error_writer(text):

228

print(f"RENDER ERROR: {text}", file=sys.stderr)

229

230

theme = get_theme(dark_background=True)

231

232

try:

233

render_tasks(

234

sys.stdout.write,

235

tasks,

236

theme=theme,

237

write_err=error_writer,

238

human_readable=True

239

)

240

print(f"\nSuccessfully processed {len(tasks)} tasks")

241

242

except Exception as e:

243

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

244

245

# Usage

246

robust_eliot_processing('eliot.log')

247

```

248

249

## Error Context and Debugging

250

251

### EliotParseError Context

252

253

```python

254

try:

255

tasks = list(tasks_from_iterable(messages))

256

except EliotParseError as e:

257

print("=== Eliot Parse Error Details ===")

258

print(f"Problematic message: {json.dumps(e.message_dict, indent=2)}")

259

print(f"Exception type: {e.exc_info[0].__name__}")

260

print(f"Exception message: {e.exc_info[1]}")

261

262

# Full traceback

263

import traceback

264

print("Full traceback:")

265

traceback.print_exception(*e.exc_info)

266

```

267

268

### JSONParseError Context

269

270

```python

271

try:

272

# JSON parsing code

273

pass

274

except JSONParseError as e:

275

print("=== JSON Parse Error Details ===")

276

print(f"File: {e.file_name}")

277

print(f"Line number: {e.line_number}")

278

print(f"Problematic content: {repr(e.line)}")

279

print(f"JSON error: {e.exc_info[1]}")

280

281

# Show surrounding context

282

with open(e.file_name, 'r') as f:

283

lines = f.readlines()

284

start = max(0, e.line_number - 3)

285

end = min(len(lines), e.line_number + 2)

286

287

print("Context:")

288

for i in range(start, end):

289

marker = ">>> " if i + 1 == e.line_number else " "

290

print(f"{marker}{i+1:4d}: {lines[i].rstrip()}")

291

```

292

293

## Common Error Scenarios

294

295

### Malformed Eliot Messages

296

297

```python

298

# Missing required fields

299

{"timestamp": 1425356936.278875} # Missing task_uuid, action_type

300

301

# Invalid field types

302

{"task_uuid": 123, "timestamp": "invalid"} # Wrong types

303

304

# Corrupted task structure

305

{"task_level": "not_a_list", "action_status": None}

306

```

307

308

### Invalid JSON Content

309

310

```python

311

# Truncated JSON

312

{"timestamp": 1425356936.278875, "action_type": "incomplete"

313

314

# Invalid escape sequences

315

{"message": "Invalid \x unicode"}

316

317

# Mixed content

318

Valid JSON line

319

Not JSON content here

320

{"another": "valid line"}

321

```

322

323

### File System Issues

324

325

- File not found or permission denied

326

- Corrupted file content or encoding issues

327

- Very large files causing memory problems

328

- Network interruptions during file access

329

330

These error classes provide the necessary context to identify, debug, and resolve issues that commonly occur when processing Eliot log data in production environments.