or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

advanced-usage.mdcore-operations.mderror-handling.mdindex.mdtypes-enums.md

error-handling.mddocs/

0

# Error Handling

1

2

Comprehensive exception hierarchy for handling template processing errors, configuration issues, user interaction problems, and system-level failures in copier operations.

3

4

## Capabilities

5

6

### Base Exceptions

7

8

Foundation exception classes for all copier errors and warnings.

9

10

```python { .api }

11

class CopierError(Exception):

12

"""Base class for all Copier errors."""

13

14

class CopierWarning(UserWarning):

15

"""Base class for all Copier warnings."""

16

```

17

18

### User-Facing Exceptions

19

20

Exceptions that indicate user-level issues requiring user action or input.

21

22

```python { .api }

23

class UserMessageError(CopierError):

24

"""Exit program with user message."""

25

26

class UnsupportedVersionError(CopierError):

27

"""Copier version doesn't support this template."""

28

29

class InteractiveSessionError(CopierError):

30

"""Interactive session required but not available."""

31

```

32

33

Usage examples:

34

35

```python

36

from copier import run_copy

37

from copier.errors import UserMessageError, UnsupportedVersionError

38

39

try:

40

worker = run_copy("template/", "project/")

41

except UserMessageError as e:

42

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

43

# Handle user-facing error gracefully

44

except UnsupportedVersionError as e:

45

print(f"Version compatibility issue: {e}")

46

# Suggest upgrading copier or using different template version

47

```

48

49

### Configuration Exceptions

50

51

Exceptions related to template configuration files and settings.

52

53

```python { .api }

54

class ConfigFileError(CopierError):

55

"""Base class for config file problems."""

56

57

class InvalidConfigFileError(ConfigFileError):

58

"""Invalid config file format or content."""

59

60

class MultipleConfigFilesError(ConfigFileError):

61

"""Multiple config files found in template."""

62

```

63

64

Usage examples:

65

66

```python

67

from copier import run_copy

68

from copier.errors import ConfigFileError, InvalidConfigFileError

69

70

try:

71

worker = run_copy("template/", "project/")

72

except InvalidConfigFileError as e:

73

print(f"Template configuration error: {e}")

74

# Check copier.yml or copier.yaml in template

75

except MultipleConfigFilesError as e:

76

print(f"Conflicting config files: {e}")

77

# Remove duplicate configuration files

78

```

79

80

### Path-Related Exceptions

81

82

Exceptions for file system path validation and access issues.

83

84

```python { .api }

85

class PathError(CopierError):

86

"""Base class for path-related errors."""

87

88

class PathNotAbsoluteError(PathError):

89

"""Path should be absolute but is relative."""

90

91

class PathNotRelativeError(PathError):

92

"""Path should be relative but is absolute."""

93

94

class ForbiddenPathError(PathError):

95

"""Path is forbidden for security reasons."""

96

```

97

98

Usage examples:

99

100

```python

101

from copier import Worker

102

from copier.errors import PathError, ForbiddenPathError

103

104

try:

105

worker = Worker(

106

src_path="template/",

107

dst_path="../../../etc/passwd" # Dangerous path

108

)

109

worker.run_copy()

110

except ForbiddenPathError as e:

111

print(f"Security violation: {e}")

112

# Use safe destination path

113

except PathError as e:

114

print(f"Path issue: {e}")

115

# Validate and correct path

116

```

117

118

### Template Processing Exceptions

119

120

Exceptions that occur during template processing and rendering.

121

122

```python { .api }

123

class InvalidTypeError(CopierError):

124

"""Unsupported question type in template."""

125

126

class ExtensionNotFoundError(CopierError):

127

"""Template extensions couldn't be loaded."""

128

129

class UnsafeTemplateError(CopierError):

130

"""Template contains unsafe features without user consent."""

131

132

class YieldTagInFileError(CopierError):

133

"""Yield tag found in file content (not allowed)."""

134

135

class MultipleYieldTagsError(CopierError):

136

"""Multiple yield tags found in path name."""

137

138

class TaskError(CopierError):

139

"""Task execution failed during template processing."""

140

141

@classmethod

142

def from_process(cls, process: subprocess.CompletedProcess) -> TaskError:

143

"""Create TaskError from a failed subprocess."""

144

```

145

146

Usage examples:

147

148

```python

149

from copier import run_copy

150

from copier.errors import UnsafeTemplateError, TaskError

151

152

try:

153

worker = run_copy(

154

"suspicious-template/",

155

"project/",

156

unsafe=False # Reject unsafe templates

157

)

158

except UnsafeTemplateError as e:

159

print(f"Template safety issue: {e}")

160

# Review template or use unsafe=True if trusted

161

except TaskError as e:

162

print(f"Template task failed: {e}")

163

# Check template tasks configuration

164

```

165

166

### User Interaction Exceptions

167

168

Exceptions related to user input and interactive sessions.

169

170

```python { .api }

171

class CopierAnswersInterrupt(CopierError):

172

"""Keyboard interrupt during questionnaire."""

173

```

174

175

Usage examples:

176

177

```python

178

from copier import run_copy

179

from copier.errors import CopierAnswersInterrupt

180

181

try:

182

worker = run_copy("template/", "project/")

183

except CopierAnswersInterrupt:

184

print("Operation cancelled by user")

185

# Clean up partial work if needed

186

except KeyboardInterrupt:

187

print("Process interrupted")

188

# Handle general interruption

189

```

190

191

### Warning Classes

192

193

Warning classes for non-fatal issues that don't stop processing.

194

195

```python { .api }

196

class UnknownCopierVersionWarning(CopierWarning):

197

"""Cannot determine which Copier version was used."""

198

199

class OldTemplateWarning(CopierWarning):

200

"""Template was designed for an older Copier version."""

201

202

class DirtyLocalWarning(CopierWarning):

203

"""Uncommitted changes in local template directory."""

204

205

class ShallowCloneWarning(CopierWarning):

206

"""Template repository is a shallow clone."""

207

208

class MissingSettingsWarning(CopierWarning):

209

"""Settings file not found at expected location."""

210

211

class MissingFileWarning(CopierWarning):

212

"""Referenced file not found in template."""

213

```

214

215

Usage examples:

216

217

```python

218

import warnings

219

from copier import run_copy

220

from copier.errors import OldTemplateWarning, DirtyLocalWarning

221

222

# Configure warning handling

223

warnings.filterwarnings("always", category=OldTemplateWarning)

224

225

try:

226

with warnings.catch_warnings(record=True) as w:

227

worker = run_copy("old-template/", "project/")

228

229

for warning in w:

230

if issubclass(warning.category, DirtyLocalWarning):

231

print(f"Template has uncommitted changes: {warning.message}")

232

elif issubclass(warning.category, OldTemplateWarning):

233

print(f"Template compatibility: {warning.message}")

234

235

except Exception as e:

236

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

237

```

238

239

### Exception Hierarchy Summary

240

241

```python

242

CopierError

243

├── UserMessageError

244

├── UnsupportedVersionError

245

├── ConfigFileError

246

│ ├── InvalidConfigFileError

247

│ └── MultipleConfigFilesError

248

├── PathError

249

│ ├── PathNotAbsoluteError

250

│ ├── PathNotRelativeError

251

│ └── ForbiddenPathError

252

├── InvalidTypeError

253

├── ExtensionNotFoundError

254

├── CopierAnswersInterrupt

255

├── UnsafeTemplateError

256

├── YieldTagInFileError

257

├── MultipleYieldTagsError

258

└── TaskError

259

260

CopierWarning

261

├── UnknownCopierVersionWarning

262

├── OldTemplateWarning

263

├── DirtyLocalWarning

264

├── ShallowCloneWarning

265

├── MissingSettingsWarning

266

├── MissingFileWarning

267

└── InteractiveSessionError

268

```

269

270

### Best Practices

271

272

```python

273

from copier import run_copy

274

from copier.errors import CopierError, ConfigFileError, PathError

275

276

def safe_template_processing(template_path: str, output_path: str) -> bool:

277

"""Safely process template with comprehensive error handling."""

278

try:

279

worker = run_copy(template_path, output_path)

280

return True

281

282

except ConfigFileError as e:

283

print(f"Template configuration issue: {e}")

284

# Log for template author to fix

285

return False

286

287

except PathError as e:

288

print(f"Path validation failed: {e}")

289

# Sanitize and retry with safe paths

290

return False

291

292

except CopierError as e:

293

print(f"Copier processing error: {e}")

294

# General copier error handling

295

return False

296

297

except Exception as e:

298

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

299

# Handle unexpected system errors

300

return False

301

```