or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

client-management.mdexception-handling.mdindex.mdrequest-handling.mdstorage-resumability.mdupload-operations.md

exception-handling.mddocs/

0

# Exception Handling

1

2

Custom exceptions for tus protocol communication errors and upload failures. TusPy provides specific exception types to help applications handle different error conditions appropriately.

3

4

## Capabilities

5

6

### TusCommunicationError

7

8

Base exception for tus server communication errors.

9

10

```python { .api }

11

class TusCommunicationError(Exception):

12

"""

13

Should be raised when communications with tus-server behaves unexpectedly.

14

15

Attributes:

16

message (str): Main message of the exception

17

status_code (int): Status code of response indicating an error

18

response_content (str): Content of response indicating an error

19

"""

20

21

def __init__(self, message: str, status_code: Optional[int] = None,

22

response_content: Optional[str] = None):

23

"""

24

Initialize TusCommunicationError.

25

26

Parameters:

27

- message (str): Error message. Can be None to generate default message using status_code

28

- status_code (Optional[int]): HTTP status code from server response

29

- response_content (Optional[str]): Content body from server response

30

"""

31

```

32

33

### TusUploadFailed

34

35

Exception for failed upload attempts, inheriting from TusCommunicationError.

36

37

```python { .api }

38

class TusUploadFailed(TusCommunicationError):

39

"""

40

Should be raised when an attempted upload fails.

41

42

Inherits all attributes and functionality from TusCommunicationError.

43

Used specifically for upload operation failures.

44

"""

45

```

46

47

### Request Error Decorator

48

49

Decorator function for converting requests library exceptions to TusCommunicationError.

50

51

```python { .api }

52

def catch_requests_error(func):

53

"""

54

Decorator to catch requests exceptions and convert to TusCommunicationError.

55

56

Wraps functions that make HTTP requests and converts any

57

requests.exceptions.RequestException to TusCommunicationError.

58

59

Parameters:

60

- func: Function to wrap

61

62

Returns:

63

Wrapped function that converts request exceptions

64

"""

65

```

66

67

## Usage Examples

68

69

### Basic Exception Handling

70

71

```python

72

from tusclient import client

73

from tusclient.exceptions import TusCommunicationError, TusUploadFailed

74

75

my_client = client.TusClient('http://tusd.tusdemo.net/files/')

76

uploader = my_client.uploader('/path/to/file.ext', chunk_size=1024*1024)

77

78

try:

79

uploader.upload()

80

print("Upload completed successfully")

81

except TusUploadFailed as e:

82

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

83

if e.status_code:

84

print(f"Server returned status code: {e.status_code}")

85

if e.response_content:

86

print(f"Server response: {e.response_content}")

87

except TusCommunicationError as e:

88

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

89

if e.status_code:

90

print(f"Status code: {e.status_code}")

91

```

92

93

### Detailed Error Information

94

95

```python

96

from tusclient import client

97

from tusclient.exceptions import TusCommunicationError, TusUploadFailed

98

99

def handle_upload_with_details(file_path: str, server_url: str):

100

my_client = client.TusClient(server_url)

101

uploader = my_client.uploader(file_path, chunk_size=1024*1024)

102

103

try:

104

uploader.upload()

105

return True, "Upload successful"

106

107

except TusUploadFailed as e:

108

error_details = {

109

'type': 'upload_failed',

110

'message': str(e),

111

'status_code': e.status_code,

112

'response_content': e.response_content

113

}

114

115

# Handle specific HTTP status codes

116

if e.status_code == 413:

117

error_details['user_message'] = "File too large for server"

118

elif e.status_code == 403:

119

error_details['user_message'] = "Upload not authorized"

120

elif e.status_code == 404:

121

error_details['user_message'] = "Upload URL not found - may have expired"

122

else:

123

error_details['user_message'] = f"Upload failed with status {e.status_code}"

124

125

return False, error_details

126

127

except TusCommunicationError as e:

128

error_details = {

129

'type': 'communication_error',

130

'message': str(e),

131

'status_code': e.status_code,

132

'user_message': "Server communication error"

133

}

134

135

return False, error_details

136

137

# Use the function

138

success, result = handle_upload_with_details('/path/to/file.ext', 'http://tusd.tusdemo.net/files/')

139

if success:

140

print(result)

141

else:

142

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

143

print(f"Details: {result['message']}")

144

```

145

146

### Retry Logic with Exception Handling

147

148

```python

149

import time

150

from tusclient import client

151

from tusclient.exceptions import TusCommunicationError, TusUploadFailed

152

153

def upload_with_custom_retry(file_path: str, server_url: str, max_retries: int = 3):

154

my_client = client.TusClient(server_url)

155

156

for attempt in range(max_retries + 1):

157

try:

158

uploader = my_client.uploader(file_path, chunk_size=1024*1024)

159

uploader.upload()

160

print(f"Upload successful on attempt {attempt + 1}")

161

return True

162

163

except TusUploadFailed as e:

164

# Don't retry on client errors (4xx)

165

if e.status_code and 400 <= e.status_code < 500:

166

print(f"Client error {e.status_code}: {e}")

167

return False

168

169

# Retry on server errors (5xx) or network issues

170

if attempt < max_retries:

171

wait_time = 2 ** attempt # Exponential backoff

172

print(f"Upload failed (attempt {attempt + 1}/{max_retries + 1}), retrying in {wait_time}s...")

173

time.sleep(wait_time)

174

else:

175

print(f"Upload failed after {max_retries + 1} attempts: {e}")

176

return False

177

178

except TusCommunicationError as e:

179

if attempt < max_retries:

180

wait_time = 2 ** attempt

181

print(f"Communication error (attempt {attempt + 1}/{max_retries + 1}), retrying in {wait_time}s...")

182

time.sleep(wait_time)

183

else:

184

print(f"Communication failed after {max_retries + 1} attempts: {e}")

185

return False

186

187

return False

188

189

# Use custom retry logic

190

success = upload_with_custom_retry('/path/to/file.ext', 'http://tusd.tusdemo.net/files/', max_retries=3)

191

```

192

193

### Async Exception Handling

194

195

```python

196

import asyncio

197

from tusclient import client

198

from tusclient.exceptions import TusCommunicationError, TusUploadFailed

199

200

async def async_upload_with_error_handling(file_path: str, server_url: str):

201

my_client = client.TusClient(server_url)

202

uploader = my_client.async_uploader(file_path, chunk_size=1024*1024)

203

204

try:

205

await uploader.upload()

206

print("Async upload completed successfully")

207

return True

208

209

except TusUploadFailed as e:

210

print(f"Async upload failed: {e}")

211

if e.status_code:

212

print(f"Status code: {e.status_code}")

213

return False

214

215

except TusCommunicationError as e:

216

print(f"Async communication error: {e}")

217

return False

218

219

# Run async upload

220

async def main():

221

success = await async_upload_with_error_handling('/path/to/file.ext', 'http://tusd.tusdemo.net/files/')

222

if success:

223

print("Upload operation completed")

224

else:

225

print("Upload operation failed")

226

227

asyncio.run(main())

228

```

229

230

### Logging Exception Details

231

232

```python

233

import logging

234

from tusclient import client

235

from tusclient.exceptions import TusCommunicationError, TusUploadFailed

236

237

# Setup logging

238

logging.basicConfig(level=logging.INFO)

239

logger = logging.getLogger(__name__)

240

241

def upload_with_logging(file_path: str, server_url: str):

242

my_client = client.TusClient(server_url)

243

uploader = my_client.uploader(file_path, chunk_size=1024*1024)

244

245

try:

246

logger.info(f"Starting upload of {file_path}")

247

uploader.upload()

248

logger.info("Upload completed successfully")

249

return True

250

251

except TusUploadFailed as e:

252

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

253

logger.error(f"Status code: {e.status_code}")

254

logger.error(f"Response content: {e.response_content}")

255

return False

256

257

except TusCommunicationError as e:

258

logger.error(f"Communication error: {e}")

259

if e.status_code:

260

logger.error(f"Status code: {e.status_code}")

261

return False

262

263

except Exception as e:

264

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

265

return False

266

267

# Use with logging

268

success = upload_with_logging('/path/to/file.ext', 'http://tusd.tusdemo.net/files/')

269

```