or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

cli.mdconvenience-functions.mddiagram-creation.mdexceptions.mdindex.mdmodel-info.mdplugin-system.md

exceptions.mddocs/

0

# Exception Classes

1

2

Erdantic defines several exception classes that provide specific error information when operations fail. These exceptions help identify and troubleshoot issues with model analysis, plugin registration, and diagram generation.

3

4

## Exception Hierarchy

5

6

```python { .api }

7

class ErdanticException(Exception):

8

"""Base class for all exceptions from erdantic library."""

9

10

class UnknownModelTypeError(ValueError, ErdanticException):

11

"""Raised when a given model does not match known model types from loaded plugins.

12

13

Attributes:

14

model (type): The model class that was not recognized.

15

available_plugins (list[str]): List of plugin keys that were available.

16

"""

17

18

class PluginNotFoundError(KeyError, ErdanticException):

19

"""Raised when specified plugin key does not match a registered plugin.

20

21

Attributes:

22

key (str): The plugin key that was not found.

23

"""

24

25

class ModelOrModuleNotFoundError(ImportError, ErdanticException):

26

"""Raised when specified fully qualified name of model class or module cannot be imported."""

27

28

class UnresolvableForwardRefError(NameError, ErdanticException):

29

"""Raised when a forward reference in a type annotation cannot be resolved automatically.

30

31

Attributes:

32

name (str): The string representation of the unresolvable forward reference.

33

model_full_name (FullyQualifiedName): The fully qualified name of the model with the forward reference.

34

"""

35

36

class UnevaluatedForwardRefError(ErdanticException):

37

"""Raised when a field's type declaration has an unevaluated forward reference.

38

39

Attributes:

40

model_full_name (FullyQualifiedName): The fully qualified name of the model with the field

41

with the unevaluated forward reference.

42

field_name (str): The name of the field with the unevaluated forward reference.

43

forward_ref (str): The string representation of the unevaluated forward reference.

44

"""

45

46

class FieldNotFoundError(AttributeError, ErdanticException):

47

"""Raised trying to access a field name that does not match any fields returned by the

48

field extractor function for a model.

49

50

Attributes:

51

name (str): The name of the field that was not found.

52

obj (object): The model object that the field was being accessed on.

53

model_full_name (FullyQualifiedName): The fully qualified name of the model.

54

"""

55

```

56

57

## Required Imports

58

59

```python

60

from erdantic.exceptions import (

61

ErdanticException, UnknownModelTypeError, PluginNotFoundError,

62

ModelOrModuleNotFoundError, UnresolvableForwardRefError,

63

UnevaluatedForwardRefError, FieldNotFoundError

64

)

65

from erdantic.core import FullyQualifiedName

66

```

67

68

## Usage Examples

69

70

### Handling Model Type Errors

71

72

```python

73

from erdantic import create

74

from erdantic.exceptions import UnknownModelTypeError

75

76

class MyCustomClass:

77

"""Not a data model class - will cause error."""

78

name: str

79

80

try:

81

diagram = create(MyCustomClass)

82

except UnknownModelTypeError as e:

83

print(f"Model not recognized: {e.model}")

84

print(f"Available plugins: {e.available_plugins}")

85

print("Make sure your class inherits from a supported data model base class")

86

```

87

88

### Handling Plugin Errors

89

90

```python

91

from erdantic.plugins import get_predicate_fn

92

from erdantic.exceptions import PluginNotFoundError

93

94

try:

95

predicate = get_predicate_fn("nonexistent_plugin")

96

except PluginNotFoundError as e:

97

print(f"Plugin '{e.key}' not found")

98

99

# Show available plugins

100

from erdantic import list_plugins

101

print(f"Available plugins: {list_plugins()}")

102

```

103

104

### Handling Import Errors

105

106

```python

107

from erdantic.cli import import_object_from_name

108

from erdantic.exceptions import ModelOrModuleNotFoundError

109

110

try:

111

model_class = import_object_from_name("nonexistent.module.Model")

112

except ModelOrModuleNotFoundError as e:

113

print(f"Could not import: {e}")

114

print("Check that the module path is correct and the module is installed")

115

```

116

117

### Handling Forward Reference Errors

118

119

```python

120

from erdantic import create

121

from erdantic.exceptions import UnresolvableForwardRefError, UnevaluatedForwardRefError

122

123

try:

124

diagram = create(MyModelWithForwardRefs)

125

except UnresolvableForwardRefError as e:

126

print(f"Cannot resolve forward reference '{e.name}' in model {e.model_full_name}")

127

print("Make sure all referenced types are properly imported or defined")

128

except UnevaluatedForwardRefError as e:

129

print(f"Unevaluated forward reference '{e.forward_ref}' in field '{e.field_name}'")

130

print(f"Model: {e.model_full_name}")

131

print("This usually indicates a plugin issue - consider reporting as a bug")

132

```

133

134

### Handling Field Access Errors

135

136

```python

137

from erdantic.core import FieldInfo, FullyQualifiedName

138

from erdantic.exceptions import FieldNotFoundError

139

140

# This would occur when accessing field information programmatically

141

try:

142

# Simulate field access that fails

143

field_info = FieldInfo(

144

model_full_name=FullyQualifiedName.from_object(MyModel),

145

name="nonexistent_field",

146

type_name="str"

147

)

148

raw_type = field_info.raw_type # This accesses the field

149

except FieldNotFoundError as e:

150

print(f"Field '{e.name}' not found on model {e.model_full_name}")

151

print("Check that the field name is correct")

152

```

153

154

### Comprehensive Error Handling

155

156

```python

157

from erdantic import draw

158

from erdantic.exceptions import (

159

ErdanticException, UnknownModelTypeError, PluginNotFoundError,

160

ModelOrModuleNotFoundError, UnresolvableForwardRefError,

161

UnevaluatedForwardRefError, FieldNotFoundError

162

)

163

164

def safe_draw_diagram(models_or_modules, output_path):

165

"""Draw diagram with comprehensive error handling."""

166

try:

167

draw(*models_or_modules, out=output_path)

168

print(f"Diagram successfully created: {output_path}")

169

170

except UnknownModelTypeError as e:

171

print(f"❌ Unknown model type: {e.model.__name__}")

172

print(f" Available plugins: {e.available_plugins}")

173

return False

174

175

except PluginNotFoundError as e:

176

print(f"❌ Plugin not found: {e.key}")

177

return False

178

179

except ModelOrModuleNotFoundError as e:

180

print(f"❌ Import error: {e}")

181

return False

182

183

except (UnresolvableForwardRefError, UnevaluatedForwardRefError) as e:

184

print(f"❌ Forward reference error: {e}")

185

return False

186

187

except FieldNotFoundError as e:

188

print(f"❌ Field access error: {e}")

189

return False

190

191

except ErdanticException as e:

192

print(f"❌ Erdantic error: {type(e).__name__}: {e}")

193

return False

194

195

except Exception as e:

196

print(f"❌ Unexpected error: {type(e).__name__}: {e}")

197

return False

198

199

return True

200

201

# Usage

202

success = safe_draw_diagram([MyModel1, MyModel2], "diagram.png")

203

if not success:

204

print("See error messages above for troubleshooting guidance")

205

```

206

207

### Error Recovery Strategies

208

209

```python

210

from erdantic import create, list_plugins

211

from erdantic.exceptions import UnknownModelTypeError, PluginNotFoundError

212

213

def create_diagram_with_fallback(models):

214

"""Create diagram with fallback strategies for common errors."""

215

216

# Strategy 1: Try creating diagram normally

217

try:

218

return create(*models)

219

except UnknownModelTypeError as e:

220

print(f"Model {e.model} not supported by current plugins")

221

222

# Strategy 2: Check if we need additional plugins

223

available = e.available_plugins

224

if "attrs" not in available:

225

print("Consider installing: pip install attrs")

226

if "msgspec" not in available:

227

print("Consider installing: pip install msgspec")

228

229

# Strategy 3: Filter to only supported models

230

supported_models = []

231

for model in models:

232

try:

233

create(model) # Test individual model

234

supported_models.append(model)

235

except UnknownModelTypeError:

236

print(f"Skipping unsupported model: {model.__name__}")

237

238

if supported_models:

239

print(f"Creating diagram with {len(supported_models)} supported models")

240

return create(*supported_models)

241

else:

242

print("No supported models found")

243

return None

244

245

# Usage

246

diagram = create_diagram_with_fallback([Model1, Model2, UnsupportedModel])

247

if diagram:

248

diagram.draw("filtered_diagram.png")

249

```

250

251

## Common Error Scenarios

252

253

### Plugin Installation Issues

254

255

When erdantic cannot find support for your model types:

256

257

```python

258

# Error: UnknownModelTypeError with attrs model

259

# Solution: pip install attrs

260

261

# Error: UnknownModelTypeError with msgspec model

262

# Solution: pip install msgspec

263

264

# Error: All models show as unsupported

265

# Solution: Check that models inherit from proper base classes

266

```

267

268

### Forward Reference Issues

269

270

When models contain forward references that cannot be resolved:

271

272

```python

273

# Common causes:

274

# 1. Missing __future__ import: from __future__ import annotations

275

# 2. Circular imports between modules

276

# 3. Type hints referencing classes not yet defined

277

# 4. Missing imports for referenced types

278

279

# Solutions:

280

# 1. Add proper imports

281

# 2. Restructure to avoid circular dependencies

282

# 3. Use string literals for forward references

283

# 4. Ensure all referenced types are accessible

284

```

285

286

### CLI Import Issues

287

288

When using the CLI with module or class paths:

289

290

```python

291

# Error: ModelOrModuleNotFoundError

292

# Common causes:

293

# 1. Typo in module/class path

294

# 2. Module not installed or not in PYTHONPATH

295

# 3. Class doesn't exist in specified module

296

297

# Solutions:

298

# 1. Verify spelling and case sensitivity

299

# 2. Check module installation: python -c "import mymodule"

300

# 3. Check class exists: python -c "from mymodule import MyClass"

301

```