taskchampion-rb 0.9.0 → 0.9.1
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/TaskchampionRbErrors.md +54 -0
- data/ext/taskchampion/src/error.rs +23 -30
- data/lib/taskchampion/version.rb +1 -1
- metadata +3 -2
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 97cd610777ff12232ab4625cbbca59e2a9241d1789926dd9a5f21d982876f25d
|
|
4
|
+
data.tar.gz: d8b3232d7fe7fe9cdc518136e08e7b3873683c90ac32cf62e1947179f53ded8c
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 61a011d70095d38bb2009a653fa151115b5327282977243cf6bc56947ab38d488b62a027470c363fe45ee40e17c5673f95857207ceb7d5f1d150b109dc60b469
|
|
7
|
+
data.tar.gz: 71e0d7baa33d944308f03d5ae5fb210b840b8834c7081980073e68f1649f2c21b86c0c7a39763a21f8c676019ae3d94bef1f82803071164c6963d59546c015c9
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
# Taskchampion Ruby Errors
|
|
2
|
+
|
|
3
|
+
## Hierarchy
|
|
4
|
+
|
|
5
|
+
```
|
|
6
|
+
StandardError
|
|
7
|
+
└── Taskchampion::Error
|
|
8
|
+
├── Taskchampion::ThreadError
|
|
9
|
+
├── Taskchampion::StorageError
|
|
10
|
+
├── Taskchampion::ValidationError
|
|
11
|
+
├── Taskchampion::ConfigError
|
|
12
|
+
└── Taskchampion::SyncError
|
|
13
|
+
└── Taskchampion::OutOfSyncError
|
|
14
|
+
```
|
|
15
|
+
|
|
16
|
+
## Error Classes
|
|
17
|
+
|
|
18
|
+
- **`Taskchampion::Error`** — Base class for all Taskchampion errors.
|
|
19
|
+
- **`Taskchampion::ThreadError`** — Raised when an object (Replica, Task, etc.) is accessed from a thread other than the one that created it.
|
|
20
|
+
- **`Taskchampion::StorageError`** — Raised for database and storage failures (`Error::Database`), and for wrapped IO/SQLite/cloud infrastructure errors (`Error::Other`).
|
|
21
|
+
- **`Taskchampion::ValidationError`** — Raised for incorrect API usage (`Error::Usage`): bad tag names, empty descriptions, invalid UUIDs, wrong argument types, invalid status symbols.
|
|
22
|
+
- **`Taskchampion::ConfigError`** — Defined for compatibility; not raised by the current TaskChampion error variants. Missing sync keyword arguments raise Ruby `ArgumentError` instead.
|
|
23
|
+
- **`Taskchampion::SyncError`** — Raised for server communication errors (`Error::Server`).
|
|
24
|
+
- **`Taskchampion::OutOfSyncError`** — Raised when the local replica is irrecoverably out of sync with the server (`Error::OutOfSync`). Subclass of `SyncError`. Signals that re-syncing from scratch is required, not just a retry.
|
|
25
|
+
|
|
26
|
+
## Mapping from TaskChampion Rust errors
|
|
27
|
+
|
|
28
|
+
| Rust variant | Ruby class |
|
|
29
|
+
|---|---|
|
|
30
|
+
| `Error::Database(msg)` | `StorageError` |
|
|
31
|
+
| `Error::Server(msg)` | `SyncError` |
|
|
32
|
+
| `Error::OutOfSync` | `OutOfSyncError` |
|
|
33
|
+
| `Error::Usage(msg)` | `ValidationError` |
|
|
34
|
+
| `Error::Other(_)` / unknown | `StorageError` |
|
|
35
|
+
|
|
36
|
+
## Usage
|
|
37
|
+
|
|
38
|
+
Rescue any error via the base class or individually:
|
|
39
|
+
|
|
40
|
+
```ruby
|
|
41
|
+
begin
|
|
42
|
+
replica.sync(config)
|
|
43
|
+
rescue Taskchampion::OutOfSyncError => e
|
|
44
|
+
# local replica is irrecoverably diverged — must re-sync from scratch
|
|
45
|
+
rescue Taskchampion::SyncError => e
|
|
46
|
+
# transient server/network error — may retry
|
|
47
|
+
rescue Taskchampion::StorageError => e
|
|
48
|
+
# database or IO failure
|
|
49
|
+
rescue Taskchampion::ValidationError => e
|
|
50
|
+
# bad input
|
|
51
|
+
rescue Taskchampion::Error => e
|
|
52
|
+
# catch-all for any Taskchampion error
|
|
53
|
+
end
|
|
54
|
+
```
|
|
@@ -6,10 +6,19 @@ pub fn init_errors(module: &RModule) -> Result<(), Error> {
|
|
|
6
6
|
module.define_error("StorageError", error_class)?;
|
|
7
7
|
module.define_error("ValidationError", error_class)?;
|
|
8
8
|
module.define_error("ConfigError", error_class)?;
|
|
9
|
-
module.define_error("SyncError", error_class)?;
|
|
9
|
+
let sync_error_class = module.define_error("SyncError", error_class)?;
|
|
10
|
+
module.define_error("OutOfSyncError", sync_error_class)?;
|
|
10
11
|
Ok(())
|
|
11
12
|
}
|
|
12
13
|
|
|
14
|
+
pub fn base_error() -> magnus::ExceptionClass {
|
|
15
|
+
let ruby = magnus::Ruby::get().expect("Ruby not available");
|
|
16
|
+
let module = ruby.class_object().const_get::<_, RModule>("Taskchampion")
|
|
17
|
+
.expect("Taskchampion module not found");
|
|
18
|
+
module.const_get::<_, magnus::ExceptionClass>("Error")
|
|
19
|
+
.expect("Error class not initialized")
|
|
20
|
+
}
|
|
21
|
+
|
|
13
22
|
pub fn thread_error() -> magnus::ExceptionClass {
|
|
14
23
|
let ruby = magnus::Ruby::get().expect("Ruby not available");
|
|
15
24
|
let module = ruby.class_object().const_get::<_, RModule>("Taskchampion")
|
|
@@ -34,45 +43,29 @@ pub fn validation_error() -> magnus::ExceptionClass {
|
|
|
34
43
|
.expect("ValidationError class not initialized")
|
|
35
44
|
}
|
|
36
45
|
|
|
37
|
-
pub fn
|
|
46
|
+
pub fn sync_error() -> magnus::ExceptionClass {
|
|
38
47
|
let ruby = magnus::Ruby::get().expect("Ruby not available");
|
|
39
48
|
let module = ruby.class_object().const_get::<_, RModule>("Taskchampion")
|
|
40
49
|
.expect("Taskchampion module not found");
|
|
41
|
-
module.const_get::<_, magnus::ExceptionClass>("
|
|
42
|
-
.expect("
|
|
50
|
+
module.const_get::<_, magnus::ExceptionClass>("SyncError")
|
|
51
|
+
.expect("SyncError class not initialized")
|
|
43
52
|
}
|
|
44
53
|
|
|
45
|
-
pub fn
|
|
54
|
+
pub fn out_of_sync_error() -> magnus::ExceptionClass {
|
|
46
55
|
let ruby = magnus::Ruby::get().expect("Ruby not available");
|
|
47
56
|
let module = ruby.class_object().const_get::<_, RModule>("Taskchampion")
|
|
48
57
|
.expect("Taskchampion module not found");
|
|
49
|
-
module.const_get::<_, magnus::ExceptionClass>("
|
|
50
|
-
.expect("
|
|
58
|
+
module.const_get::<_, magnus::ExceptionClass>("OutOfSyncError")
|
|
59
|
+
.expect("OutOfSyncError class not initialized")
|
|
51
60
|
}
|
|
52
61
|
|
|
53
|
-
// Enhanced error mapping function with context-aware error types
|
|
54
62
|
pub fn map_taskchampion_error(error: taskchampion::Error) -> Error {
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
Error::new(
|
|
61
|
-
|
|
62
|
-
error_msg.contains("network") || error_msg.contains("remote") {
|
|
63
|
-
Error::new(sync_error(), format!("Synchronization error: {}", error_msg))
|
|
64
|
-
} else if error_msg.contains("config") || error_msg.contains("invalid config") {
|
|
65
|
-
Error::new(config_error(), format!("Configuration error: {}", error_msg))
|
|
66
|
-
} else if error_msg.contains("invalid") || error_msg.contains("parse") ||
|
|
67
|
-
error_msg.contains("format") || error_msg.contains("validation") {
|
|
68
|
-
Error::new(validation_error(), format!("Validation error: {}", error_msg))
|
|
69
|
-
} else {
|
|
70
|
-
// Generic TaskChampion error for unknown types
|
|
71
|
-
let ruby = magnus::Ruby::get().expect("Ruby not available");
|
|
72
|
-
let module = ruby.class_object().const_get::<_, RModule>("Taskchampion")
|
|
73
|
-
.expect("Taskchampion module not found");
|
|
74
|
-
let error_class = module.const_get::<_, magnus::ExceptionClass>("Error")
|
|
75
|
-
.expect("Error class not initialized");
|
|
76
|
-
Error::new(error_class, format!("TaskChampion error: {}", error_msg))
|
|
63
|
+
match error {
|
|
64
|
+
taskchampion::Error::Database(msg) => Error::new(storage_error(), msg),
|
|
65
|
+
taskchampion::Error::Server(msg) => Error::new(sync_error(), msg),
|
|
66
|
+
taskchampion::Error::OutOfSync => Error::new(out_of_sync_error(),
|
|
67
|
+
"Local replica is out of sync with the server"),
|
|
68
|
+
taskchampion::Error::Usage(msg) => Error::new(validation_error(), msg),
|
|
69
|
+
_ => Error::new(storage_error(), error.to_string()),
|
|
77
70
|
}
|
|
78
71
|
}
|
data/lib/taskchampion/version.rb
CHANGED
metadata
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: taskchampion-rb
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.9.
|
|
4
|
+
version: 0.9.1
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Tim Case
|
|
8
8
|
autorequire:
|
|
9
9
|
bindir: exe
|
|
10
10
|
cert_chain: []
|
|
11
|
-
date:
|
|
11
|
+
date: 2026-05-23 00:00:00.000000000 Z
|
|
12
12
|
dependencies:
|
|
13
13
|
- !ruby/object:Gem::Dependency
|
|
14
14
|
name: rb_sys
|
|
@@ -41,6 +41,7 @@ files:
|
|
|
41
41
|
- Cargo.toml
|
|
42
42
|
- README.md
|
|
43
43
|
- Rakefile
|
|
44
|
+
- TaskchampionRbErrors.md
|
|
44
45
|
- docs/ANNOTATION_IMPLEMENTATION.md
|
|
45
46
|
- docs/API_REFERENCE.md
|
|
46
47
|
- docs/THREAD_SAFETY.md
|