monday_ruby 1.1.0 → 1.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/.env +1 -1
- data/.rubocop.yml +2 -1
- data/CHANGELOG.md +14 -0
- data/CONTRIBUTING.md +104 -0
- data/README.md +146 -142
- data/docs/.vitepress/config.mjs +255 -0
- data/docs/.vitepress/theme/index.js +4 -0
- data/docs/.vitepress/theme/style.css +43 -0
- data/docs/README.md +80 -0
- data/docs/explanation/architecture.md +507 -0
- data/docs/explanation/best-practices/errors.md +478 -0
- data/docs/explanation/best-practices/performance.md +1084 -0
- data/docs/explanation/best-practices/rate-limiting.md +630 -0
- data/docs/explanation/best-practices/testing.md +820 -0
- data/docs/explanation/column-values.md +857 -0
- data/docs/explanation/design.md +795 -0
- data/docs/explanation/graphql.md +356 -0
- data/docs/explanation/migration/v1.md +808 -0
- data/docs/explanation/pagination.md +447 -0
- data/docs/guides/advanced/batch.md +1274 -0
- data/docs/guides/advanced/complex-queries.md +1114 -0
- data/docs/guides/advanced/errors.md +818 -0
- data/docs/guides/advanced/pagination.md +934 -0
- data/docs/guides/advanced/rate-limiting.md +981 -0
- data/docs/guides/authentication.md +286 -0
- data/docs/guides/boards/create.md +386 -0
- data/docs/guides/boards/delete.md +405 -0
- data/docs/guides/boards/duplicate.md +511 -0
- data/docs/guides/boards/query.md +530 -0
- data/docs/guides/boards/update.md +453 -0
- data/docs/guides/columns/create.md +452 -0
- data/docs/guides/columns/metadata.md +492 -0
- data/docs/guides/columns/query.md +455 -0
- data/docs/guides/columns/update-multiple.md +459 -0
- data/docs/guides/columns/update-values.md +509 -0
- data/docs/guides/files/add-to-column.md +40 -0
- data/docs/guides/files/add-to-update.md +37 -0
- data/docs/guides/files/clear-column.md +33 -0
- data/docs/guides/first-request.md +285 -0
- data/docs/guides/folders/manage.md +750 -0
- data/docs/guides/groups/items.md +626 -0
- data/docs/guides/groups/manage.md +501 -0
- data/docs/guides/installation.md +169 -0
- data/docs/guides/items/create.md +493 -0
- data/docs/guides/items/delete.md +514 -0
- data/docs/guides/items/query.md +605 -0
- data/docs/guides/items/subitems.md +483 -0
- data/docs/guides/items/update.md +699 -0
- data/docs/guides/updates/manage.md +619 -0
- data/docs/guides/use-cases/dashboard.md +1421 -0
- data/docs/guides/use-cases/import.md +1962 -0
- data/docs/guides/use-cases/task-management.md +1381 -0
- data/docs/guides/workspaces/manage.md +502 -0
- data/docs/index.md +69 -0
- data/docs/package-lock.json +2468 -0
- data/docs/package.json +13 -0
- data/docs/reference/client.md +540 -0
- data/docs/reference/configuration.md +586 -0
- data/docs/reference/errors.md +693 -0
- data/docs/reference/resources/account.md +208 -0
- data/docs/reference/resources/activity-log.md +369 -0
- data/docs/reference/resources/board-view.md +359 -0
- data/docs/reference/resources/board.md +393 -0
- data/docs/reference/resources/column.md +543 -0
- data/docs/reference/resources/file.md +236 -0
- data/docs/reference/resources/folder.md +386 -0
- data/docs/reference/resources/group.md +507 -0
- data/docs/reference/resources/item.md +348 -0
- data/docs/reference/resources/subitem.md +267 -0
- data/docs/reference/resources/update.md +259 -0
- data/docs/reference/resources/workspace.md +213 -0
- data/docs/reference/response.md +560 -0
- data/docs/tutorial/first-integration.md +713 -0
- data/lib/monday/client.rb +24 -0
- data/lib/monday/configuration.rb +5 -0
- data/lib/monday/request.rb +15 -0
- data/lib/monday/resources/base.rb +4 -0
- data/lib/monday/resources/file.rb +56 -0
- data/lib/monday/util.rb +1 -0
- data/lib/monday/version.rb +1 -1
- metadata +87 -4
|
@@ -0,0 +1,693 @@
|
|
|
1
|
+
# Errors
|
|
2
|
+
|
|
3
|
+
Exception classes for handling monday.com API errors.
|
|
4
|
+
|
|
5
|
+
## Overview
|
|
6
|
+
|
|
7
|
+
The monday_ruby gem provides a comprehensive error handling system that maps HTTP status codes and monday.com GraphQL error codes to specific Ruby exception classes. All errors inherit from `Monday::Error`, making it easy to catch and handle monday.com-related errors in your application.
|
|
8
|
+
|
|
9
|
+
### When Errors Are Raised
|
|
10
|
+
|
|
11
|
+
Errors are raised in two scenarios:
|
|
12
|
+
|
|
13
|
+
1. **HTTP Status Codes**: Non-2xx status codes (400, 401, 403, 404, 429, 500)
|
|
14
|
+
2. **GraphQL Error Codes**: Even when HTTP status is 200, GraphQL error_code values trigger specific exceptions
|
|
15
|
+
|
|
16
|
+
```ruby
|
|
17
|
+
# HTTP 401 raises Monday::AuthorizationError
|
|
18
|
+
client = Monday::Client.new(token: "invalid_token")
|
|
19
|
+
client.account.query
|
|
20
|
+
# => Monday::AuthorizationError
|
|
21
|
+
|
|
22
|
+
# HTTP 200 with error_code raises Monday::InvalidRequestError
|
|
23
|
+
client.board.query(args: {ids: [999999]})
|
|
24
|
+
# => Monday::InvalidRequestError: InvalidBoardIdException
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
## Error Hierarchy
|
|
28
|
+
|
|
29
|
+
All errors inherit from `Monday::Error < StandardError`:
|
|
30
|
+
|
|
31
|
+
```
|
|
32
|
+
Monday::Error
|
|
33
|
+
├── Monday::AuthorizationError
|
|
34
|
+
├── Monday::InvalidRequestError
|
|
35
|
+
├── Monday::ResourceNotFoundError
|
|
36
|
+
├── Monday::RateLimitError
|
|
37
|
+
├── Monday::InternalServerError
|
|
38
|
+
└── Monday::ComplexityError
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
## Base Error Class
|
|
42
|
+
|
|
43
|
+
### Monday::Error
|
|
44
|
+
|
|
45
|
+
Base error class from which all monday_ruby exceptions inherit.
|
|
46
|
+
|
|
47
|
+
**Inherits:** `StandardError`
|
|
48
|
+
|
|
49
|
+
**Attributes:**
|
|
50
|
+
|
|
51
|
+
| Name | Type | Description |
|
|
52
|
+
|------|------|-------------|
|
|
53
|
+
| `message` | String | Human-readable error message |
|
|
54
|
+
| `code` | Integer or String | HTTP status code or GraphQL error code |
|
|
55
|
+
| `response` | Monday::Response | Full response object (if available) |
|
|
56
|
+
|
|
57
|
+
**Methods:**
|
|
58
|
+
|
|
59
|
+
| Name | Returns | Description |
|
|
60
|
+
|------|---------|-------------|
|
|
61
|
+
| `error_data` | Hash | Additional error metadata from `response.body["error_data"]` |
|
|
62
|
+
|
|
63
|
+
**Example:**
|
|
64
|
+
|
|
65
|
+
```ruby
|
|
66
|
+
begin
|
|
67
|
+
client.board.query(args: {ids: [123]})
|
|
68
|
+
rescue Monday::Error => e
|
|
69
|
+
puts e.message # => "The board does not exist..."
|
|
70
|
+
puts e.code # => "InvalidBoardIdException" or 404
|
|
71
|
+
puts e.response # => Monday::Response object
|
|
72
|
+
puts e.error_data # => {"board_id" => 123}
|
|
73
|
+
end
|
|
74
|
+
```
|
|
75
|
+
|
|
76
|
+
## Exception Classes
|
|
77
|
+
|
|
78
|
+
### Monday::AuthorizationError
|
|
79
|
+
|
|
80
|
+
Raised when authentication fails or the user lacks required permissions.
|
|
81
|
+
|
|
82
|
+
**HTTP Status Codes:** 401, 403
|
|
83
|
+
|
|
84
|
+
**GraphQL Error Codes:**
|
|
85
|
+
- `UserUnauthorizedException`
|
|
86
|
+
- `USER_UNAUTHORIZED`
|
|
87
|
+
|
|
88
|
+
**Common Causes:**
|
|
89
|
+
- Invalid or expired API token
|
|
90
|
+
- Token doesn't have required scopes/permissions
|
|
91
|
+
- Token has been revoked
|
|
92
|
+
- Attempting to access resources without proper authorization
|
|
93
|
+
|
|
94
|
+
**Example:**
|
|
95
|
+
|
|
96
|
+
```ruby
|
|
97
|
+
begin
|
|
98
|
+
client = Monday::Client.new(token: "invalid_token")
|
|
99
|
+
client.account.query(select: ["id", "name"])
|
|
100
|
+
|
|
101
|
+
rescue Monday::AuthorizationError => e
|
|
102
|
+
puts "Authentication failed: #{e.message}"
|
|
103
|
+
puts "Please verify your API token in the monday.com Developer Portal"
|
|
104
|
+
end
|
|
105
|
+
```
|
|
106
|
+
|
|
107
|
+
**Typical Response:**
|
|
108
|
+
|
|
109
|
+
```json
|
|
110
|
+
{
|
|
111
|
+
"errors": ["Not Authenticated"],
|
|
112
|
+
"status": 401
|
|
113
|
+
}
|
|
114
|
+
```
|
|
115
|
+
|
|
116
|
+
**See:** [Error Handling guide](/guides/advanced/errors#authorizationerror-401-403)
|
|
117
|
+
|
|
118
|
+
---
|
|
119
|
+
|
|
120
|
+
### Monday::InvalidRequestError
|
|
121
|
+
|
|
122
|
+
Raised when request parameters are invalid or malformed.
|
|
123
|
+
|
|
124
|
+
**HTTP Status Code:** 400
|
|
125
|
+
|
|
126
|
+
**GraphQL Error Codes:**
|
|
127
|
+
- `InvalidUserIdException`
|
|
128
|
+
- `InvalidVersionException`
|
|
129
|
+
- `InvalidColumnIdException`
|
|
130
|
+
- `InvalidItemIdException`
|
|
131
|
+
- `InvalidSubitemIdException`
|
|
132
|
+
- `InvalidBoardIdException`
|
|
133
|
+
- `InvalidGroupIdException`
|
|
134
|
+
- `InvalidArgumentException`
|
|
135
|
+
- `CreateBoardException`
|
|
136
|
+
- `ItemsLimitationException`
|
|
137
|
+
- `ItemNameTooLongException`
|
|
138
|
+
- `ColumnValueException`
|
|
139
|
+
- `CorrectedValueException`
|
|
140
|
+
- `InvalidWorkspaceIdException`
|
|
141
|
+
|
|
142
|
+
**Common Causes:**
|
|
143
|
+
- Invalid board, item, column, or group IDs
|
|
144
|
+
- Malformed GraphQL query syntax
|
|
145
|
+
- Invalid column values or formats
|
|
146
|
+
- Item names exceeding 255 characters
|
|
147
|
+
- Missing required parameters
|
|
148
|
+
- Attempting to create boards with invalid attributes
|
|
149
|
+
|
|
150
|
+
**Example:**
|
|
151
|
+
|
|
152
|
+
```ruby
|
|
153
|
+
begin
|
|
154
|
+
response = client.item.create(
|
|
155
|
+
args: {
|
|
156
|
+
board_id: 999999, # Invalid board ID
|
|
157
|
+
item_name: "New Task"
|
|
158
|
+
},
|
|
159
|
+
select: ["id", "name"]
|
|
160
|
+
)
|
|
161
|
+
|
|
162
|
+
rescue Monday::InvalidRequestError => e
|
|
163
|
+
puts "Invalid request: #{e.message}"
|
|
164
|
+
|
|
165
|
+
# Access specific error details
|
|
166
|
+
if e.error_data["board_id"]
|
|
167
|
+
puts "Invalid board ID: #{e.error_data["board_id"]}"
|
|
168
|
+
elsif e.error_data["item_id"]
|
|
169
|
+
puts "Invalid item ID: #{e.error_data["item_id"]}"
|
|
170
|
+
elsif e.error_data["column_id"]
|
|
171
|
+
puts "Invalid column ID: #{e.error_data["column_id"]}"
|
|
172
|
+
end
|
|
173
|
+
end
|
|
174
|
+
```
|
|
175
|
+
|
|
176
|
+
**Typical Response:**
|
|
177
|
+
|
|
178
|
+
```json
|
|
179
|
+
{
|
|
180
|
+
"error_message": "The board does not exist. Please check your board ID and try again",
|
|
181
|
+
"error_code": "InvalidBoardIdException",
|
|
182
|
+
"error_data": {"board_id": 999999},
|
|
183
|
+
"status_code": 200
|
|
184
|
+
}
|
|
185
|
+
```
|
|
186
|
+
|
|
187
|
+
**See:** [Error Handling guide](/guides/advanced/errors#invalidrequesterror-400)
|
|
188
|
+
|
|
189
|
+
---
|
|
190
|
+
|
|
191
|
+
### Monday::ResourceNotFoundError
|
|
192
|
+
|
|
193
|
+
Raised when a requested resource does not exist.
|
|
194
|
+
|
|
195
|
+
**HTTP Status Code:** 404
|
|
196
|
+
|
|
197
|
+
**GraphQL Error Codes:**
|
|
198
|
+
- `ResourceNotFoundException`
|
|
199
|
+
|
|
200
|
+
**Common Causes:**
|
|
201
|
+
- Resource has been deleted
|
|
202
|
+
- Resource never existed
|
|
203
|
+
- User doesn't have access to the resource
|
|
204
|
+
- Incorrect resource ID
|
|
205
|
+
|
|
206
|
+
**Example:**
|
|
207
|
+
|
|
208
|
+
```ruby
|
|
209
|
+
begin
|
|
210
|
+
response = client.folder.delete(args: {folder_id: 123456})
|
|
211
|
+
|
|
212
|
+
rescue Monday::ResourceNotFoundError => e
|
|
213
|
+
puts "Resource not found: #{e.message}"
|
|
214
|
+
puts "The folder may have already been deleted"
|
|
215
|
+
|
|
216
|
+
# This is often an acceptable outcome
|
|
217
|
+
# No need to re-raise
|
|
218
|
+
end
|
|
219
|
+
```
|
|
220
|
+
|
|
221
|
+
**Typical Response:**
|
|
222
|
+
|
|
223
|
+
```json
|
|
224
|
+
{
|
|
225
|
+
"error_message": "The folder does not exist. Please check your folder ID and try again",
|
|
226
|
+
"error_code": "ResourceNotFoundException",
|
|
227
|
+
"error_data": {"folder_id": 123456},
|
|
228
|
+
"status_code": 200
|
|
229
|
+
}
|
|
230
|
+
```
|
|
231
|
+
|
|
232
|
+
**See:** [Error Handling guide](/guides/advanced/errors#resourcenotfounderror-404)
|
|
233
|
+
|
|
234
|
+
---
|
|
235
|
+
|
|
236
|
+
### Monday::RateLimitError
|
|
237
|
+
|
|
238
|
+
Raised when API rate limits are exceeded.
|
|
239
|
+
|
|
240
|
+
**HTTP Status Code:** 429
|
|
241
|
+
|
|
242
|
+
**GraphQL Error Codes:**
|
|
243
|
+
- `ComplexityException` (when used for rate limiting)
|
|
244
|
+
- `COMPLEXITY_BUDGET_EXHAUSTED`
|
|
245
|
+
|
|
246
|
+
**Common Causes:**
|
|
247
|
+
- Too many requests in a short time period
|
|
248
|
+
- Exceeding complexity budget (10,000,000 per minute for queries)
|
|
249
|
+
- Exceeding mutation limit (60 per minute per user)
|
|
250
|
+
|
|
251
|
+
**Rate Limits:**
|
|
252
|
+
- **Queries**: Complexity-based, max 10,000,000 complexity per minute
|
|
253
|
+
- **Mutations**: 60 requests per minute per user
|
|
254
|
+
|
|
255
|
+
**Example:**
|
|
256
|
+
|
|
257
|
+
```ruby
|
|
258
|
+
begin
|
|
259
|
+
response = client.board.query(
|
|
260
|
+
args: {limit: 100},
|
|
261
|
+
select: ["id", "name", {"items" => ["id", "name", "column_values"]}]
|
|
262
|
+
)
|
|
263
|
+
|
|
264
|
+
rescue Monday::RateLimitError => e
|
|
265
|
+
puts "Rate limit exceeded: #{e.message}"
|
|
266
|
+
|
|
267
|
+
# Wait before retrying
|
|
268
|
+
puts "Waiting 60 seconds before retry..."
|
|
269
|
+
sleep 60
|
|
270
|
+
retry
|
|
271
|
+
end
|
|
272
|
+
```
|
|
273
|
+
|
|
274
|
+
**Typical Response:**
|
|
275
|
+
|
|
276
|
+
```json
|
|
277
|
+
{
|
|
278
|
+
"error_message": "You have exceeded your rate limit",
|
|
279
|
+
"error_code": "COMPLEXITY_BUDGET_EXHAUSTED",
|
|
280
|
+
"status_code": 429
|
|
281
|
+
}
|
|
282
|
+
```
|
|
283
|
+
|
|
284
|
+
**See:**
|
|
285
|
+
- [Error Handling guide](/guides/advanced/errors#ratelimiterror-429)
|
|
286
|
+
- [Rate Limiting guide](/guides/advanced/rate-limiting)
|
|
287
|
+
|
|
288
|
+
---
|
|
289
|
+
|
|
290
|
+
### Monday::InternalServerError
|
|
291
|
+
|
|
292
|
+
Raised when monday.com's servers encounter an internal error.
|
|
293
|
+
|
|
294
|
+
**HTTP Status Code:** 500
|
|
295
|
+
|
|
296
|
+
**GraphQL Error Codes:**
|
|
297
|
+
- `INTERNAL_SERVER_ERROR`
|
|
298
|
+
|
|
299
|
+
**Common Causes:**
|
|
300
|
+
- monday.com service outages or degradations
|
|
301
|
+
- Server-side bugs in monday.com API
|
|
302
|
+
- Temporary infrastructure issues
|
|
303
|
+
- Invalid data causing server-side errors
|
|
304
|
+
|
|
305
|
+
**Example:**
|
|
306
|
+
|
|
307
|
+
```ruby
|
|
308
|
+
def create_with_retry(client, args, max_retries: 3)
|
|
309
|
+
retry_count = 0
|
|
310
|
+
|
|
311
|
+
begin
|
|
312
|
+
client.item.create(args: args, select: ["id", "name"])
|
|
313
|
+
|
|
314
|
+
rescue Monday::InternalServerError => e
|
|
315
|
+
retry_count += 1
|
|
316
|
+
|
|
317
|
+
if retry_count < max_retries
|
|
318
|
+
delay = 2 ** retry_count # Exponential backoff: 2s, 4s, 8s
|
|
319
|
+
puts "Server error (attempt #{retry_count}/#{max_retries}). Retrying in #{delay}s..."
|
|
320
|
+
sleep delay
|
|
321
|
+
retry
|
|
322
|
+
else
|
|
323
|
+
puts "Server error persists after #{max_retries} attempts"
|
|
324
|
+
raise
|
|
325
|
+
end
|
|
326
|
+
end
|
|
327
|
+
end
|
|
328
|
+
```
|
|
329
|
+
|
|
330
|
+
**Typical Response:**
|
|
331
|
+
|
|
332
|
+
```json
|
|
333
|
+
{
|
|
334
|
+
"status_code": 500,
|
|
335
|
+
"error_message": "Internal server error",
|
|
336
|
+
"error_code": "INTERNAL_SERVER_ERROR"
|
|
337
|
+
}
|
|
338
|
+
```
|
|
339
|
+
|
|
340
|
+
**See:** [Error Handling guide](/guides/advanced/errors#internalservererror-500)
|
|
341
|
+
|
|
342
|
+
---
|
|
343
|
+
|
|
344
|
+
### Monday::ComplexityError
|
|
345
|
+
|
|
346
|
+
Raised when GraphQL query complexity is too high.
|
|
347
|
+
|
|
348
|
+
**GraphQL Error Codes:**
|
|
349
|
+
- `ComplexityException`
|
|
350
|
+
|
|
351
|
+
**Common Causes:**
|
|
352
|
+
- Requesting too many nested fields
|
|
353
|
+
- Querying too many items at once
|
|
354
|
+
- Complex queries with deep nesting
|
|
355
|
+
- Requesting large amounts of data in a single query
|
|
356
|
+
|
|
357
|
+
**Example:**
|
|
358
|
+
|
|
359
|
+
```ruby
|
|
360
|
+
begin
|
|
361
|
+
# This query might be too complex
|
|
362
|
+
response = client.board.query(
|
|
363
|
+
args: {limit: 100},
|
|
364
|
+
select: [
|
|
365
|
+
"id",
|
|
366
|
+
"name",
|
|
367
|
+
{"groups" => [
|
|
368
|
+
"id",
|
|
369
|
+
"title",
|
|
370
|
+
{"items" => [
|
|
371
|
+
"id",
|
|
372
|
+
"name",
|
|
373
|
+
{"column_values" => ["id", "text", "value"]}
|
|
374
|
+
]}
|
|
375
|
+
]}
|
|
376
|
+
]
|
|
377
|
+
)
|
|
378
|
+
|
|
379
|
+
rescue Monday::ComplexityError => e
|
|
380
|
+
puts "Query too complex: #{e.message}"
|
|
381
|
+
|
|
382
|
+
# Simplify the query
|
|
383
|
+
response = client.board.query(
|
|
384
|
+
args: {limit: 25}, # Reduce limit
|
|
385
|
+
select: ["id", "name", {"groups" => ["id", "title"]}] # Less nesting
|
|
386
|
+
)
|
|
387
|
+
end
|
|
388
|
+
```
|
|
389
|
+
|
|
390
|
+
**See:**
|
|
391
|
+
- [Error Handling guide](/guides/advanced/errors)
|
|
392
|
+
- [Complex Queries guide](/guides/advanced/complex-queries)
|
|
393
|
+
|
|
394
|
+
## Error Code Mapping
|
|
395
|
+
|
|
396
|
+
### HTTP Status Codes
|
|
397
|
+
|
|
398
|
+
| Status Code | Exception Class |
|
|
399
|
+
|-------------|----------------|
|
|
400
|
+
| 400 | `Monday::InvalidRequestError` |
|
|
401
|
+
| 401 | `Monday::AuthorizationError` |
|
|
402
|
+
| 403 | `Monday::AuthorizationError` |
|
|
403
|
+
| 404 | `Monday::ResourceNotFoundError` |
|
|
404
|
+
| 429 | `Monday::RateLimitError` |
|
|
405
|
+
| 500 | `Monday::InternalServerError` |
|
|
406
|
+
| Other | `Monday::Error` |
|
|
407
|
+
|
|
408
|
+
### GraphQL Error Codes
|
|
409
|
+
|
|
410
|
+
| Error Code | Exception Class | HTTP Status |
|
|
411
|
+
|------------|----------------|-------------|
|
|
412
|
+
| `UserUnauthorizedException` | `Monday::AuthorizationError` | 403 |
|
|
413
|
+
| `USER_UNAUTHORIZED` | `Monday::AuthorizationError` | 403 |
|
|
414
|
+
| `ResourceNotFoundException` | `Monday::ResourceNotFoundError` | 404 |
|
|
415
|
+
| `InvalidUserIdException` | `Monday::InvalidRequestError` | 400 |
|
|
416
|
+
| `InvalidVersionException` | `Monday::InvalidRequestError` | 400 |
|
|
417
|
+
| `InvalidColumnIdException` | `Monday::InvalidRequestError` | 400 |
|
|
418
|
+
| `InvalidItemIdException` | `Monday::InvalidRequestError` | 400 |
|
|
419
|
+
| `InvalidSubitemIdException` | `Monday::InvalidRequestError` | 400 |
|
|
420
|
+
| `InvalidBoardIdException` | `Monday::InvalidRequestError` | 400 |
|
|
421
|
+
| `InvalidGroupIdException` | `Monday::InvalidRequestError` | 400 |
|
|
422
|
+
| `InvalidArgumentException` | `Monday::InvalidRequestError` | 400 |
|
|
423
|
+
| `CreateBoardException` | `Monday::InvalidRequestError` | 400 |
|
|
424
|
+
| `ItemsLimitationException` | `Monday::InvalidRequestError` | 400 |
|
|
425
|
+
| `ItemNameTooLongException` | `Monday::InvalidRequestError` | 400 |
|
|
426
|
+
| `ColumnValueException` | `Monday::InvalidRequestError` | 400 |
|
|
427
|
+
| `CorrectedValueException` | `Monday::InvalidRequestError` | 400 |
|
|
428
|
+
| `InvalidWorkspaceIdException` | `Monday::InvalidRequestError` | 400 |
|
|
429
|
+
| `ComplexityException` | `Monday::ComplexityError` or `Monday::RateLimitError` | 429 |
|
|
430
|
+
| `COMPLEXITY_BUDGET_EXHAUSTED` | `Monday::RateLimitError` | 429 |
|
|
431
|
+
| `INTERNAL_SERVER_ERROR` | `Monday::InternalServerError` | 500 |
|
|
432
|
+
|
|
433
|
+
## Rescue Patterns
|
|
434
|
+
|
|
435
|
+
### Catch All monday.com Errors
|
|
436
|
+
|
|
437
|
+
```ruby
|
|
438
|
+
begin
|
|
439
|
+
response = client.board.query(args: {ids: [123]})
|
|
440
|
+
rescue Monday::Error => e
|
|
441
|
+
puts "monday.com error: #{e.message}"
|
|
442
|
+
puts "Error code: #{e.code}"
|
|
443
|
+
end
|
|
444
|
+
```
|
|
445
|
+
|
|
446
|
+
### Catch Specific Error Types
|
|
447
|
+
|
|
448
|
+
```ruby
|
|
449
|
+
begin
|
|
450
|
+
response = client.item.create(
|
|
451
|
+
args: {board_id: 123, item_name: "Task"},
|
|
452
|
+
select: ["id", "name"]
|
|
453
|
+
)
|
|
454
|
+
|
|
455
|
+
rescue Monday::AuthorizationError => e
|
|
456
|
+
puts "Authentication failed"
|
|
457
|
+
|
|
458
|
+
rescue Monday::InvalidRequestError => e
|
|
459
|
+
puts "Invalid request: #{e.message}"
|
|
460
|
+
|
|
461
|
+
rescue Monday::RateLimitError => e
|
|
462
|
+
puts "Rate limited. Waiting..."
|
|
463
|
+
sleep 60
|
|
464
|
+
retry
|
|
465
|
+
|
|
466
|
+
rescue Monday::Error => e
|
|
467
|
+
puts "Unexpected error: #{e.message}"
|
|
468
|
+
end
|
|
469
|
+
```
|
|
470
|
+
|
|
471
|
+
### Access Error Details
|
|
472
|
+
|
|
473
|
+
```ruby
|
|
474
|
+
begin
|
|
475
|
+
client.board.delete(999999)
|
|
476
|
+
|
|
477
|
+
rescue Monday::Error => e
|
|
478
|
+
# Message
|
|
479
|
+
puts e.message
|
|
480
|
+
# => "The board does not exist. Please check your board ID and try again"
|
|
481
|
+
|
|
482
|
+
# Code
|
|
483
|
+
puts e.code
|
|
484
|
+
# => "InvalidBoardIdException" or 404
|
|
485
|
+
|
|
486
|
+
# Response object
|
|
487
|
+
puts e.response.status
|
|
488
|
+
# => 200 or 404
|
|
489
|
+
|
|
490
|
+
puts e.response.body
|
|
491
|
+
# => {"error_message" => "...", "error_code" => "...", ...}
|
|
492
|
+
|
|
493
|
+
# Error data
|
|
494
|
+
puts e.error_data
|
|
495
|
+
# => {"board_id" => 999999}
|
|
496
|
+
end
|
|
497
|
+
```
|
|
498
|
+
|
|
499
|
+
### Multiple Rescue Blocks
|
|
500
|
+
|
|
501
|
+
```ruby
|
|
502
|
+
def safe_create_item(client, board_id, item_name)
|
|
503
|
+
client.item.create(
|
|
504
|
+
args: {board_id: board_id, item_name: item_name},
|
|
505
|
+
select: ["id", "name"]
|
|
506
|
+
)
|
|
507
|
+
|
|
508
|
+
rescue Monday::AuthorizationError => e
|
|
509
|
+
logger.error("Auth error: #{e.message}")
|
|
510
|
+
nil
|
|
511
|
+
|
|
512
|
+
rescue Monday::InvalidRequestError => e
|
|
513
|
+
logger.warn("Invalid input: #{e.message}")
|
|
514
|
+
nil
|
|
515
|
+
|
|
516
|
+
rescue Monday::ResourceNotFoundError => e
|
|
517
|
+
logger.info("Resource not found: #{e.message}")
|
|
518
|
+
nil
|
|
519
|
+
|
|
520
|
+
rescue Monday::RateLimitError => e
|
|
521
|
+
logger.warn("Rate limited, retrying...")
|
|
522
|
+
sleep 60
|
|
523
|
+
retry
|
|
524
|
+
|
|
525
|
+
rescue Monday::InternalServerError => e
|
|
526
|
+
logger.error("Server error: #{e.message}")
|
|
527
|
+
nil
|
|
528
|
+
|
|
529
|
+
rescue Monday::Error => e
|
|
530
|
+
logger.error("Unexpected error: #{e.class} - #{e.message}")
|
|
531
|
+
raise # Re-raise unexpected errors
|
|
532
|
+
end
|
|
533
|
+
```
|
|
534
|
+
|
|
535
|
+
## Usage Examples
|
|
536
|
+
|
|
537
|
+
### Basic Error Handling
|
|
538
|
+
|
|
539
|
+
```ruby
|
|
540
|
+
response = client.board.query(args: {ids: [123]})
|
|
541
|
+
|
|
542
|
+
if response.success?
|
|
543
|
+
boards = response.body["data"]["boards"]
|
|
544
|
+
puts "Found #{boards.length} boards"
|
|
545
|
+
else
|
|
546
|
+
puts "Request failed: #{response.body["error_message"]}"
|
|
547
|
+
end
|
|
548
|
+
```
|
|
549
|
+
|
|
550
|
+
### With Retry Logic
|
|
551
|
+
|
|
552
|
+
```ruby
|
|
553
|
+
max_retries = 3
|
|
554
|
+
retry_count = 0
|
|
555
|
+
|
|
556
|
+
begin
|
|
557
|
+
response = client.item.create(
|
|
558
|
+
args: {board_id: 123, item_name: "New Task"},
|
|
559
|
+
select: ["id", "name"]
|
|
560
|
+
)
|
|
561
|
+
|
|
562
|
+
item = response.body["data"]["create_item"]
|
|
563
|
+
|
|
564
|
+
rescue Monday::RateLimitError => e
|
|
565
|
+
# Always retry rate limits
|
|
566
|
+
sleep 60
|
|
567
|
+
retry
|
|
568
|
+
|
|
569
|
+
rescue Monday::InternalServerError => e
|
|
570
|
+
retry_count += 1
|
|
571
|
+
|
|
572
|
+
if retry_count < max_retries
|
|
573
|
+
delay = 2 ** retry_count
|
|
574
|
+
sleep delay
|
|
575
|
+
retry
|
|
576
|
+
else
|
|
577
|
+
raise
|
|
578
|
+
end
|
|
579
|
+
|
|
580
|
+
rescue Monday::Error => e
|
|
581
|
+
puts "Error: #{e.message}"
|
|
582
|
+
nil
|
|
583
|
+
end
|
|
584
|
+
```
|
|
585
|
+
|
|
586
|
+
### Conditional Error Handling
|
|
587
|
+
|
|
588
|
+
```ruby
|
|
589
|
+
def delete_board_safely(client, board_id)
|
|
590
|
+
begin
|
|
591
|
+
response = client.board.delete(board_id)
|
|
592
|
+
puts "Board deleted successfully"
|
|
593
|
+
true
|
|
594
|
+
|
|
595
|
+
rescue Monday::ResourceNotFoundError => e
|
|
596
|
+
puts "Board not found (already deleted?)"
|
|
597
|
+
true # Not an error - board is gone
|
|
598
|
+
|
|
599
|
+
rescue Monday::AuthorizationError => e
|
|
600
|
+
puts "Not authorized to delete board"
|
|
601
|
+
false
|
|
602
|
+
|
|
603
|
+
rescue Monday::Error => e
|
|
604
|
+
puts "Failed to delete board: #{e.message}"
|
|
605
|
+
false
|
|
606
|
+
end
|
|
607
|
+
end
|
|
608
|
+
```
|
|
609
|
+
|
|
610
|
+
### Extract Error Information
|
|
611
|
+
|
|
612
|
+
```ruby
|
|
613
|
+
begin
|
|
614
|
+
response = client.column.change_simple_value(
|
|
615
|
+
args: {
|
|
616
|
+
board_id: 123,
|
|
617
|
+
item_id: 456,
|
|
618
|
+
column_id: "status",
|
|
619
|
+
value: "Done"
|
|
620
|
+
}
|
|
621
|
+
)
|
|
622
|
+
|
|
623
|
+
rescue Monday::InvalidRequestError => e
|
|
624
|
+
puts "Error code: #{e.code}"
|
|
625
|
+
# => "InvalidBoardIdException"
|
|
626
|
+
|
|
627
|
+
puts "Error message: #{e.message}"
|
|
628
|
+
# => "The board does not exist..."
|
|
629
|
+
|
|
630
|
+
puts "HTTP status: #{e.response.status}"
|
|
631
|
+
# => 200
|
|
632
|
+
|
|
633
|
+
puts "Error data: #{e.error_data.inspect}"
|
|
634
|
+
# => {"board_id" => 123}
|
|
635
|
+
|
|
636
|
+
# Check what's invalid
|
|
637
|
+
if e.error_data["board_id"]
|
|
638
|
+
puts "Invalid board ID: #{e.error_data["board_id"]}"
|
|
639
|
+
elsif e.error_data["item_id"]
|
|
640
|
+
puts "Invalid item ID: #{e.error_data["item_id"]}"
|
|
641
|
+
elsif e.error_data["column_id"]
|
|
642
|
+
puts "Invalid column ID: #{e.error_data["column_id"]}"
|
|
643
|
+
end
|
|
644
|
+
end
|
|
645
|
+
```
|
|
646
|
+
|
|
647
|
+
### Fallback Values
|
|
648
|
+
|
|
649
|
+
```ruby
|
|
650
|
+
def get_board_name(client, board_id)
|
|
651
|
+
response = client.board.query(
|
|
652
|
+
args: {ids: [board_id]},
|
|
653
|
+
select: ["id", "name"]
|
|
654
|
+
)
|
|
655
|
+
|
|
656
|
+
response.body.dig("data", "boards", 0, "name")
|
|
657
|
+
|
|
658
|
+
rescue Monday::ResourceNotFoundError
|
|
659
|
+
"Board not found"
|
|
660
|
+
|
|
661
|
+
rescue Monday::AuthorizationError
|
|
662
|
+
"Access denied"
|
|
663
|
+
|
|
664
|
+
rescue Monday::Error => e
|
|
665
|
+
"Error: #{e.message}"
|
|
666
|
+
end
|
|
667
|
+
```
|
|
668
|
+
|
|
669
|
+
## Best Practices
|
|
670
|
+
|
|
671
|
+
1. **Rescue Specific Errors**: Catch specific error classes rather than the base `Monday::Error`
|
|
672
|
+
2. **Use error_data**: Access `error_data` for context-specific information (invalid IDs, etc.)
|
|
673
|
+
3. **Check response.success?**: For non-critical paths, check success status instead of rescuing
|
|
674
|
+
4. **Retry Appropriately**: Always retry `RateLimitError`, consider retrying `InternalServerError`
|
|
675
|
+
5. **Log Errors**: Log error details for debugging and monitoring
|
|
676
|
+
6. **Re-raise When Needed**: Re-raise errors you can't handle to avoid hiding issues
|
|
677
|
+
7. **Validate Input**: Validate parameters before making API calls to prevent errors
|
|
678
|
+
8. **Provide Fallbacks**: Return default values or partial data when appropriate
|
|
679
|
+
9. **User-Friendly Messages**: Convert technical errors to readable messages for end users
|
|
680
|
+
10. **Test Error Paths**: Write tests for error handling code
|
|
681
|
+
|
|
682
|
+
## Related Resources
|
|
683
|
+
|
|
684
|
+
- [Error Handling Guide](/guides/advanced/errors) - Comprehensive error handling guide with patterns
|
|
685
|
+
- [Rate Limiting Guide](/guides/advanced/rate-limiting) - Understanding and handling rate limits
|
|
686
|
+
- [Client](/reference/client) - Main client class that raises errors
|
|
687
|
+
- [Response](/reference/response) - Response object accessed via `error.response`
|
|
688
|
+
|
|
689
|
+
## External References
|
|
690
|
+
|
|
691
|
+
- [monday.com API Errors](https://developer.monday.com/api-reference/docs/errors)
|
|
692
|
+
- [monday.com Rate Limits](https://developer.monday.com/api-reference/docs/rate-limits)
|
|
693
|
+
- [GraphQL Error Handling](https://graphql.org/learn/validation/)
|