taskchampion-rb 0.6.0 → 0.7.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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 494521791e308dacc686f45ef7ff87937a0038e46729092a4e145952971a5f56
4
- data.tar.gz: ac3a7b7367b2d8565ac902981fb4c7a9ee45b7d0c825868b15591211debc733b
3
+ metadata.gz: cafd2930e70aef0ac31c03c98e3d806cd1fba49408ce69b4bcb5d41074465c3f
4
+ data.tar.gz: 23b8948a759f8cc7b28e2cb68d65d40750943bd05bf127a87f5e25bf80116900
5
5
  SHA512:
6
- metadata.gz: 3d5c1e59e10ac46d98a8fc30d666dac904fcf2d14742c12713a16050a7a67d87c21e1a42ebaf7d25762541d0335c3c36ab2cf6a93bd3ed778046cd1a739840f4
7
- data.tar.gz: 8f69921b628b5b1803a940584b05dd46abc854e50d9a3555646a141298a6c2a55008b2c8ca60b508fd53566bc6d0bd28a69f8caf76021e37a56e9fbf69bd362c
6
+ metadata.gz: 2ff558c7674c2ff686e08ec9e220baa966edf438353e42832a566771cbcb2348c329d34fa27937b7bc9b71c0fdd7721f6e3086a675a5baa4e54f2e4e102600a5
7
+ data.tar.gz: 34dfcc7ea08bc2f90b846d3a19b1526731a0142d1cc6d09a867923bd6620be3abc13602eab12f8022c85dfc10b3f97502c62419808db3b942808489efbd51488
data/docs/errors.md ADDED
@@ -0,0 +1,151 @@
1
+ # TaskChampion Ruby Error Reference
2
+
3
+ ## Error Hierarchy
4
+
5
+ All TaskChampion errors inherit from `Taskchampion::Error`, which inherits from Ruby's `StandardError`.
6
+
7
+ ```
8
+ StandardError
9
+ └── Taskchampion::Error
10
+ ├── Taskchampion::ThreadError
11
+ ├── Taskchampion::StorageError
12
+ ├── Taskchampion::ValidationError
13
+ ├── Taskchampion::ConfigError
14
+ └── Taskchampion::SyncError
15
+ ```
16
+
17
+ ## Error Types
18
+
19
+ ### Taskchampion::ValidationError
20
+
21
+ Raised when data validation fails, including:
22
+ - Invalid UUID format
23
+ - Invalid datetime format
24
+ - Parse errors
25
+ - Format validation failures
26
+
27
+ **Example:**
28
+ ```ruby
29
+ # Invalid UUID format
30
+ replica.create_task("bad-uuid", operations)
31
+ # => Taskchampion::ValidationError: Invalid UUID format: 'bad-uuid'. Expected format: xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx
32
+ ```
33
+
34
+ ### Taskchampion::ThreadError
35
+
36
+ Raised when an object is accessed from a different thread than the one that created it. TaskChampion enforces thread safety by requiring objects to be accessed only from their creation thread.
37
+
38
+ **Example:**
39
+ ```ruby
40
+ replica = Taskchampion::Replica.new_in_memory
41
+ Thread.new { replica.all_tasks }.join
42
+ # => Taskchampion::ThreadError: Object accessed from wrong thread
43
+ ```
44
+
45
+ ### Taskchampion::StorageError
46
+
47
+ Raised for database and storage-related issues:
48
+ - File not found
49
+ - Permission denied
50
+ - Database corruption
51
+ - Storage access failures
52
+
53
+ **Example:**
54
+ ```ruby
55
+ Taskchampion::Replica.new_on_disk("/invalid/path", false)
56
+ # => Taskchampion::StorageError: Storage error: No such file or directory
57
+ ```
58
+
59
+ ### Taskchampion::ConfigError
60
+
61
+ Raised when configuration is invalid or missing required parameters:
62
+ - Invalid configuration values
63
+ - Missing required configuration
64
+
65
+ **Example:**
66
+ ```ruby
67
+ # Missing required sync configuration
68
+ replica.sync_to_remote(url: "https://example.com")
69
+ # => Taskchampion::ConfigError: Configuration error: missing client_id
70
+ ```
71
+
72
+ ### Taskchampion::SyncError
73
+
74
+ Raised during synchronization operations:
75
+ - Network failures
76
+ - Server connection issues
77
+ - Remote sync problems
78
+ - Authentication failures
79
+
80
+ **Example:**
81
+ ```ruby
82
+ replica.sync_to_remote(
83
+ url: "https://invalid.server",
84
+ client_id: "...",
85
+ encryption_secret: "..."
86
+ )
87
+ # => Taskchampion::SyncError: Synchronization error: network timeout
88
+ ```
89
+
90
+ ### Taskchampion::Error
91
+
92
+ Generic error class for TaskChampion errors that don't fall into specific categories. This is the base class for all TaskChampion-specific errors.
93
+
94
+ ## Common Error Scenarios
95
+
96
+ ### Creating Tasks
97
+
98
+ ```ruby
99
+ begin
100
+ task = replica.create_task(uuid, operations)
101
+ rescue Taskchampion::ValidationError => e
102
+ # Handle invalid UUID format
103
+ puts "Invalid UUID: #{e.message}"
104
+ rescue Taskchampion::StorageError => e
105
+ # Handle storage issues
106
+ puts "Storage problem: #{e.message}"
107
+ rescue Taskchampion::ThreadError => e
108
+ # Handle thread safety violation
109
+ puts "Thread error: #{e.message}"
110
+ end
111
+ ```
112
+
113
+ ### Synchronization
114
+
115
+ ```ruby
116
+ begin
117
+ replica.sync_to_remote(
118
+ url: server_url,
119
+ client_id: client_id,
120
+ encryption_secret: secret
121
+ )
122
+ rescue Taskchampion::SyncError => e
123
+ # Handle sync failures
124
+ puts "Sync failed: #{e.message}"
125
+ rescue Taskchampion::ConfigError => e
126
+ # Handle configuration issues
127
+ puts "Config error: #{e.message}"
128
+ end
129
+ ```
130
+
131
+ ### File Operations
132
+
133
+ ```ruby
134
+ begin
135
+ replica = Taskchampion::Replica.new_on_disk(path, false, :read_write)
136
+ rescue Taskchampion::StorageError => e
137
+ # Handle file access issues
138
+ puts "Cannot access database: #{e.message}"
139
+ end
140
+ ```
141
+
142
+ ## Error Message Patterns
143
+
144
+ The error mapping system examines error message content to determine the appropriate exception type:
145
+
146
+ - Messages containing "storage", "database", "No such file", or "Permission denied" → `StorageError`
147
+ - Messages containing "sync", "server", "network", or "remote" → `SyncError`
148
+ - Messages containing "config" or "invalid config" → `ConfigError`
149
+ - Messages containing "invalid", "parse", "format", or "validation" → `ValidationError`
150
+ - Thread access violations → `ThreadError`
151
+ - All other TaskChampion errors → `Error` (base class)
@@ -53,4 +53,4 @@ pending.each_with_index do |task, index|
53
53
  end
54
54
 
55
55
  puts "\n" + "=" * 50
56
- puts "For comparison, all_tasks returns #{replica.all_tasks.size} tasks total"
56
+ puts "For comparison, all_tasks returns #{replica.all_tasks.size} tasks total"
@@ -264,6 +264,15 @@ impl Task {
264
264
  Ok(())
265
265
  }
266
266
 
267
+ fn set_entry(&self, entry: Value, operations: &crate::operations::Operations) -> Result<(), Error> {
268
+ let mut task = self.0.get_mut()?;
269
+ let entry_datetime = ruby_to_option(entry, ruby_to_datetime)?;
270
+ operations.with_inner_mut(|ops| {
271
+ task.set_entry(entry_datetime, ops)
272
+ })?;
273
+ Ok(())
274
+ }
275
+
267
276
  fn set_value(&self, property: String, value: Value, operations: &crate::operations::Operations) -> Result<(), Error> {
268
277
  if property.trim().is_empty() {
269
278
  return Err(Error::new(
@@ -389,6 +398,7 @@ pub fn init(module: &RModule) -> Result<(), Error> {
389
398
  class.define_method("remove_tag", method!(Task::remove_tag, 2))?;
390
399
  class.define_method("add_annotation", method!(Task::add_annotation, 2))?;
391
400
  class.define_method("set_due", method!(Task::set_due, 2))?;
401
+ class.define_method("set_entry", method!(Task::set_entry, 2))?;
392
402
  class.define_method("set_value", method!(Task::set_value, 3))?;
393
403
  class.define_method("set_uda", method!(Task::set_uda, 4))?;
394
404
  class.define_method("delete_uda", method!(Task::delete_uda, 3))?;
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Taskchampion
4
- VERSION = "0.6.0"
4
+ VERSION = "0.7.0"
5
5
  end
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.6.0
4
+ version: 0.7.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Tim Case
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2025-08-14 00:00:00.000000000 Z
11
+ date: 2025-08-18 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rb_sys
@@ -45,6 +45,7 @@ files:
45
45
  - docs/THREAD_SAFETY.md
46
46
  - docs/breakthrough.md
47
47
  - docs/description.md
48
+ - docs/errors.md
48
49
  - docs/phase_3_plan.md
49
50
  - docs/plan.md
50
51
  - example.md