monday_ruby 1.0.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.
Files changed (93) hide show
  1. checksums.yaml +4 -4
  2. data/.env +1 -1
  3. data/.rspec +0 -1
  4. data/.rubocop.yml +19 -0
  5. data/.simplecov +1 -0
  6. data/CHANGELOG.md +49 -0
  7. data/CONTRIBUTING.md +165 -0
  8. data/README.md +167 -88
  9. data/docs/.vitepress/config.mjs +255 -0
  10. data/docs/.vitepress/theme/index.js +4 -0
  11. data/docs/.vitepress/theme/style.css +43 -0
  12. data/docs/README.md +80 -0
  13. data/docs/explanation/architecture.md +507 -0
  14. data/docs/explanation/best-practices/errors.md +478 -0
  15. data/docs/explanation/best-practices/performance.md +1084 -0
  16. data/docs/explanation/best-practices/rate-limiting.md +630 -0
  17. data/docs/explanation/best-practices/testing.md +820 -0
  18. data/docs/explanation/column-values.md +857 -0
  19. data/docs/explanation/design.md +795 -0
  20. data/docs/explanation/graphql.md +356 -0
  21. data/docs/explanation/migration/v1.md +808 -0
  22. data/docs/explanation/pagination.md +447 -0
  23. data/docs/guides/advanced/batch.md +1274 -0
  24. data/docs/guides/advanced/complex-queries.md +1114 -0
  25. data/docs/guides/advanced/errors.md +818 -0
  26. data/docs/guides/advanced/pagination.md +934 -0
  27. data/docs/guides/advanced/rate-limiting.md +981 -0
  28. data/docs/guides/authentication.md +286 -0
  29. data/docs/guides/boards/create.md +386 -0
  30. data/docs/guides/boards/delete.md +405 -0
  31. data/docs/guides/boards/duplicate.md +511 -0
  32. data/docs/guides/boards/query.md +530 -0
  33. data/docs/guides/boards/update.md +453 -0
  34. data/docs/guides/columns/create.md +452 -0
  35. data/docs/guides/columns/metadata.md +492 -0
  36. data/docs/guides/columns/query.md +455 -0
  37. data/docs/guides/columns/update-multiple.md +459 -0
  38. data/docs/guides/columns/update-values.md +509 -0
  39. data/docs/guides/files/add-to-column.md +40 -0
  40. data/docs/guides/files/add-to-update.md +37 -0
  41. data/docs/guides/files/clear-column.md +33 -0
  42. data/docs/guides/first-request.md +285 -0
  43. data/docs/guides/folders/manage.md +750 -0
  44. data/docs/guides/groups/items.md +626 -0
  45. data/docs/guides/groups/manage.md +501 -0
  46. data/docs/guides/installation.md +169 -0
  47. data/docs/guides/items/create.md +493 -0
  48. data/docs/guides/items/delete.md +514 -0
  49. data/docs/guides/items/query.md +605 -0
  50. data/docs/guides/items/subitems.md +483 -0
  51. data/docs/guides/items/update.md +699 -0
  52. data/docs/guides/updates/manage.md +619 -0
  53. data/docs/guides/use-cases/dashboard.md +1421 -0
  54. data/docs/guides/use-cases/import.md +1962 -0
  55. data/docs/guides/use-cases/task-management.md +1381 -0
  56. data/docs/guides/workspaces/manage.md +502 -0
  57. data/docs/index.md +69 -0
  58. data/docs/package-lock.json +2468 -0
  59. data/docs/package.json +13 -0
  60. data/docs/reference/client.md +540 -0
  61. data/docs/reference/configuration.md +586 -0
  62. data/docs/reference/errors.md +693 -0
  63. data/docs/reference/resources/account.md +208 -0
  64. data/docs/reference/resources/activity-log.md +369 -0
  65. data/docs/reference/resources/board-view.md +359 -0
  66. data/docs/reference/resources/board.md +393 -0
  67. data/docs/reference/resources/column.md +543 -0
  68. data/docs/reference/resources/file.md +236 -0
  69. data/docs/reference/resources/folder.md +386 -0
  70. data/docs/reference/resources/group.md +507 -0
  71. data/docs/reference/resources/item.md +348 -0
  72. data/docs/reference/resources/subitem.md +267 -0
  73. data/docs/reference/resources/update.md +259 -0
  74. data/docs/reference/resources/workspace.md +213 -0
  75. data/docs/reference/response.md +560 -0
  76. data/docs/tutorial/first-integration.md +713 -0
  77. data/lib/monday/client.rb +41 -2
  78. data/lib/monday/configuration.rb +13 -0
  79. data/lib/monday/deprecation.rb +23 -0
  80. data/lib/monday/error.rb +5 -2
  81. data/lib/monday/request.rb +19 -1
  82. data/lib/monday/resources/base.rb +4 -0
  83. data/lib/monday/resources/board.rb +52 -0
  84. data/lib/monday/resources/column.rb +6 -0
  85. data/lib/monday/resources/file.rb +56 -0
  86. data/lib/monday/resources/folder.rb +55 -0
  87. data/lib/monday/resources/group.rb +66 -0
  88. data/lib/monday/resources/item.rb +62 -0
  89. data/lib/monday/util.rb +33 -1
  90. data/lib/monday/version.rb +1 -1
  91. data/lib/monday_ruby.rb +1 -0
  92. metadata +92 -11
  93. data/monday_ruby.gemspec +0 -39
@@ -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/)