ace-handbook 0.19.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 +7 -0
- data/.ace-defaults/handbook/config.yml +4 -0
- data/.ace-defaults/nav/protocols/guide-sources/ace-handbook.yml +19 -0
- data/.ace-defaults/nav/protocols/tmpl-sources/ace-handbook.yml +10 -0
- data/.ace-defaults/nav/protocols/wfi-sources/ace-handbook.yml +19 -0
- data/CHANGELOG.md +362 -0
- data/LICENSE +21 -0
- data/README.md +42 -0
- data/Rakefile +12 -0
- data/exe/ace-handbook +6 -0
- data/handbook/guides/ai-agent-integration.g.md +625 -0
- data/handbook/guides/atom-pattern.g.md +371 -0
- data/handbook/guides/changelog.g.md +333 -0
- data/handbook/guides/cli-dry-cli.g.md +276 -0
- data/handbook/guides/cli-support-cli.g.md +277 -0
- data/handbook/guides/coding-standards/ruby.md +41 -0
- data/handbook/guides/coding-standards/rust.md +19 -0
- data/handbook/guides/coding-standards/typescript.md +20 -0
- data/handbook/guides/coding-standards.g.md +134 -0
- data/handbook/guides/debug-troubleshooting.g.md +62 -0
- data/handbook/guides/error-handling/ruby.md +29 -0
- data/handbook/guides/error-handling/rust.md +59 -0
- data/handbook/guides/error-handling/typescript.md +38 -0
- data/handbook/guides/error-handling.g.md +207 -0
- data/handbook/guides/meta/agents-definition.g.md +823 -0
- data/handbook/guides/meta/guides-definition.g.md +322 -0
- data/handbook/guides/meta/markdown-definition.g.md +210 -0
- data/handbook/guides/meta/tools-definition.g.md +159 -0
- data/handbook/guides/meta/workflow-instructions-definition.g.md +367 -0
- data/handbook/guides/mono-repo-patterns.g.md +92 -0
- data/handbook/guides/multi-agent-research.g.md +251 -0
- data/handbook/guides/performance/ruby.md +25 -0
- data/handbook/guides/performance/rust.md +48 -0
- data/handbook/guides/performance/typescript.md +32 -0
- data/handbook/guides/performance.g.md +211 -0
- data/handbook/guides/prompt-caching.g.md +83 -0
- data/handbook/guides/quality-assurance/ruby.md +33 -0
- data/handbook/guides/quality-assurance/rust.md +41 -0
- data/handbook/guides/quality-assurance/typescript.md +49 -0
- data/handbook/guides/quality-assurance.g.md +222 -0
- data/handbook/guides/strategic-planning.g.md +69 -0
- data/handbook/guides/troubleshooting/ruby.md +21 -0
- data/handbook/guides/troubleshooting/rust.md +20 -0
- data/handbook/guides/troubleshooting/typescript.md +36 -0
- data/handbook/guides/workflow-context-embedding.g.md +286 -0
- data/handbook/skills/as-handbook-init-project/SKILL.md +34 -0
- data/handbook/skills/as-handbook-manage-agents/SKILL.md +35 -0
- data/handbook/skills/as-handbook-manage-guides/SKILL.md +35 -0
- data/handbook/skills/as-handbook-manage-workflows/SKILL.md +35 -0
- data/handbook/skills/as-handbook-parallel-research/SKILL.md +29 -0
- data/handbook/skills/as-handbook-perform-delivery/SKILL.md +35 -0
- data/handbook/skills/as-handbook-review-guides/SKILL.md +32 -0
- data/handbook/skills/as-handbook-review-workflows/SKILL.md +32 -0
- data/handbook/skills/as-handbook-synthesize-research/SKILL.md +29 -0
- data/handbook/skills/as-handbook-update-docs/SKILL.md +35 -0
- data/handbook/skills/as-release/SKILL.md +50 -0
- data/handbook/skills/as-release-bump-version/SKILL.md +28 -0
- data/handbook/skills/as-release-rubygems-publish/SKILL.md +58 -0
- data/handbook/skills/as-release-update-changelog/SKILL.md +28 -0
- data/handbook/templates/completed-work-documentation.md +59 -0
- data/handbook/templates/cookbooks/cookbook.template.md +237 -0
- data/handbook/templates/research-comparison.template.md +175 -0
- data/handbook/workflow-instructions/handbook/init-project.wf.md +629 -0
- data/handbook/workflow-instructions/handbook/manage-agents.wf.md +379 -0
- data/handbook/workflow-instructions/handbook/manage-guides.wf.md +294 -0
- data/handbook/workflow-instructions/handbook/manage-workflows.wf.md +292 -0
- data/handbook/workflow-instructions/handbook/parallel-research.wf.md +328 -0
- data/handbook/workflow-instructions/handbook/perform-delivery.wf.md +267 -0
- data/handbook/workflow-instructions/handbook/research.wf.md +247 -0
- data/handbook/workflow-instructions/handbook/review-guides.wf.md +348 -0
- data/handbook/workflow-instructions/handbook/review-workflows.wf.md +299 -0
- data/handbook/workflow-instructions/handbook/synthesize-research.wf.md +429 -0
- data/handbook/workflow-instructions/handbook/update-docs.wf.md +338 -0
- data/lib/ace/handbook/atoms/provider_registry.rb +70 -0
- data/lib/ace/handbook/cli/commands/status.rb +36 -0
- data/lib/ace/handbook/cli/commands/sync.rb +36 -0
- data/lib/ace/handbook/cli.rb +51 -0
- data/lib/ace/handbook/models/skill_document.rb +25 -0
- data/lib/ace/handbook/molecules/skill_projection.rb +54 -0
- data/lib/ace/handbook/organisms/provider_syncer.rb +106 -0
- data/lib/ace/handbook/organisms/skill_inventory.rb +54 -0
- data/lib/ace/handbook/organisms/status_collector.rb +181 -0
- data/lib/ace/handbook/version.rb +7 -0
- data/lib/ace/handbook.rb +28 -0
- metadata +227 -0
|
@@ -0,0 +1,134 @@
|
|
|
1
|
+
---
|
|
2
|
+
doc-type: guide
|
|
3
|
+
title: General Coding Standards
|
|
4
|
+
purpose: Documentation for ace-handbook/handbook/guides/coding-standards.g.md
|
|
5
|
+
ace-docs:
|
|
6
|
+
last-updated: 2026-01-08
|
|
7
|
+
last-checked: 2026-03-21
|
|
8
|
+
---
|
|
9
|
+
|
|
10
|
+
# General Coding Standards
|
|
11
|
+
|
|
12
|
+
## Goal
|
|
13
|
+
|
|
14
|
+
This guide outlines the fundamental principles and standards for writing clean, readable, maintainable,
|
|
15
|
+
and consistent code within this project. Adhering to these standards facilitates collaboration
|
|
16
|
+
(human-human and human-AI) and long-term project health.
|
|
17
|
+
|
|
18
|
+
This document outlines general coding standards applicable across the project. Project-specific
|
|
19
|
+
conventions or language-specific rules beyond these general principles may be documented
|
|
20
|
+
in the relevant `dev-taskflow/` directory or linked from the `docs/blueprint.md`.
|
|
21
|
+
|
|
22
|
+
## General Principles
|
|
23
|
+
|
|
24
|
+
- **Clarity & Readability:** Write code that is easy for others (and your future self) to understand. Use
|
|
25
|
+
meaningful variable names, keep functions/methods short and focused, and add comments where logic is
|
|
26
|
+
complex or non-obvious.
|
|
27
|
+
- **Consistency:** Follow established patterns and conventions within the project. If using a style guide tool
|
|
28
|
+
(like StandardRB, RuboCop), adhere to its rules.
|
|
29
|
+
- **Simplicity (KISS):** Avoid unnecessary complexity. Prefer straightforward solutions unless a more complex
|
|
30
|
+
approach offers significant, justifiable benefits (e.g., performance).
|
|
31
|
+
- **Don\'t Repeat Yourself (DRY):** Abstract common logic into reusable functions, methods, or classes.
|
|
32
|
+
- **Modularity:** Design components with clear responsibilities and well-defined interfaces. Aim for loose
|
|
33
|
+
coupling and high cohesion.
|
|
34
|
+
- **Testability:** Write code that is easy to test. Use dependency injection and avoid tight coupling to
|
|
35
|
+
|
|
36
|
+
## Language-Specific Coding Standards
|
|
37
|
+
|
|
38
|
+
Language-specific idioms, conventions, and tool recommendations have been moved to dedicated sub-guides.
|
|
39
|
+
Please refer to the relevant guide for your language:
|
|
40
|
+
|
|
41
|
+
- [Ruby Coding Standards](./coding-standards/ruby.md)
|
|
42
|
+
- [TypeScript Coding Standards](./coding-standards/typescript.md)
|
|
43
|
+
|
|
44
|
+
## Formatting & Style
|
|
45
|
+
|
|
46
|
+
- **Indentation:** Use consistent indentation (e.g., 2 spaces for Ruby).
|
|
47
|
+
- **Line Length:** Adhere to a reasonable line length limit (e.g., 100-120 characters) to improve
|
|
48
|
+
readability.
|
|
49
|
+
- **Whitespace:** Use whitespace effectively to separate logical blocks of code.
|
|
50
|
+
- **Tooling:** Utilize automated formatters and linters (e.g., StandardRB, Prettier) to enforce
|
|
51
|
+
consistency. Configure these tools via project configuration files (e.g., `.standard.yml`, `.prettierrc`).
|
|
52
|
+
|
|
53
|
+
## Error Handling
|
|
54
|
+
|
|
55
|
+
- Use specific, informative error classes. Define a base error class for the project/library.
|
|
56
|
+
- Provide context with errors (e.g., relevant data, operation being performed).
|
|
57
|
+
- Handle errors appropriately (log, retry, raise, return error values) based on the context.
|
|
58
|
+
- See [Error Handling Guide](./error-handling.g.md) for more details.
|
|
59
|
+
|
|
60
|
+
## Testing
|
|
61
|
+
|
|
62
|
+
- Write tests for new code (unit, integration, E2E as appropriate).
|
|
63
|
+
- Ensure tests cover primary functionality, edge cases, and error conditions.
|
|
64
|
+
- Keep tests independent and fast.
|
|
65
|
+
- See [Testing Guidelines](guide://testing) for more details.
|
|
66
|
+
|
|
67
|
+
## Documentation
|
|
68
|
+
|
|
69
|
+
- Document public APIs (classes, methods, modules) using standard documentation tools (e.g., YARD for Ruby).
|
|
70
|
+
- Add comments to explain complex logic or non-obvious decisions within method bodies.
|
|
71
|
+
- Keep documentation up-to-date with code changes.
|
|
72
|
+
- See [Documentation Standards](guide://documentation) for more details.
|
|
73
|
+
|
|
74
|
+
## File Organization
|
|
75
|
+
|
|
76
|
+
- Follow a logical directory structure (e.g., separating library code, tests, configuration, documentation).
|
|
77
|
+
- Use clear and consistent file naming conventions.
|
|
78
|
+
Refer to the project's `docs/blueprint.md` for the specific structure.
|
|
79
|
+
|
|
80
|
+
## AI-Assisted Development Collaboration
|
|
81
|
+
|
|
82
|
+
When working with AI coding agents (like Cursor, Claude, etc.), treat them as collaborative partners, often akin
|
|
83
|
+
to a junior developer needing clear guidance.
|
|
84
|
+
|
|
85
|
+
- **Plan Before Prompting:** Thoroughly plan the task, including outlining steps, defining requirements, and
|
|
86
|
+
identifying relevant context *before* asking the AI to generate or modify code. This aligns with the
|
|
87
|
+
"Slow Vibe Coding" principle mentioned in Project Management.
|
|
88
|
+
- **Provide Context:** Give the AI sufficient context, including relevant code snippets, project structure
|
|
89
|
+
(`docs/blueprint.md`), architecture (`docs/architecture.md`), existing patterns, and the
|
|
90
|
+
specific task definition (`.md` file within `dev-taskflow`).
|
|
91
|
+
- **Use Specific, Concise Instructions:** Avoid vague requests. Break down complex tasks into smaller,
|
|
92
|
+
well-defined steps. Use clear action verbs and specify the desired outcome. Consider using "prompt hygiene"
|
|
93
|
+
like "ONLY IMPLEMENT EXACTLY THIS STEP" for focused changes.
|
|
94
|
+
- **Structured Prompts:** Structure prompts clearly, defining the AI\'s role, the objective, step-by-step instructions,
|
|
95
|
+
and the desired output format (XML is often preferred by models like GPT-4.1). Include examples (few-shot learning)
|
|
96
|
+
where appropriate.
|
|
97
|
+
- **Review Rigorously:** Review AI-generated code with the same scrutiny as human-written code. Check for
|
|
98
|
+
correctness, adherence to standards, edge cases, security, and performance implications. Do not blindly
|
|
99
|
+
trust AI output.
|
|
100
|
+
- **Iterate and Refine:** Expect to iterate. Provide constructive feedback on the AI\'s output to guide it
|
|
101
|
+
towards the desired solution. Ask for explanations of its logic to learn and verify understanding.
|
|
102
|
+
- **Leverage Strengths:** Use AI for tasks it excels at (e.g., boilerplate code, implementing well-defined
|
|
103
|
+
algorithms, refactoring based on clear rules) but rely on human oversight for complex design decisions
|
|
104
|
+
and architectural planning.
|
|
105
|
+
- **Avoid "Hacky" Prompts:** Modern models respond better to clear instructions than tricks like excessive
|
|
106
|
+
capitalization or emotional appeals.
|
|
107
|
+
|
|
108
|
+
Refer to the [Project Management Guide](guide://project-management) for how AI collaboration fits
|
|
109
|
+
into the task workflow.
|
|
110
|
+
|
|
111
|
+
(Example structure - adjust based on project)
|
|
112
|
+
|
|
113
|
+
```text
|
|
114
|
+
project-root/
|
|
115
|
+
├── lib/ # Core library code
|
|
116
|
+
│ └── my_module/
|
|
117
|
+
├── spec/ # Tests
|
|
118
|
+
│ ├── unit/
|
|
119
|
+
│ ├── integration/
|
|
120
|
+
│ └── support/
|
|
121
|
+
├── config/ # Configuration files
|
|
122
|
+
├── docs/ # User-facing documentation
|
|
123
|
+
├── ace-handbook/ # Development handbook (internal docs)
|
|
124
|
+
├── bin/ # Executable scripts
|
|
125
|
+
└── Rakefile / Makefile / etc. # Build/task runner configuration
|
|
126
|
+
```
|
|
127
|
+
|
|
128
|
+
## Related Documentation
|
|
129
|
+
|
|
130
|
+
- [Error Handling Guide](./error-handling.g.md)
|
|
131
|
+
- [Testing Guidelines](guide://testing)
|
|
132
|
+
- [Documentation Standards](guide://documentation)
|
|
133
|
+
- [Temporary File Management Guidelines](./temporary-file-management.g.md)
|
|
134
|
+
- [Project Management Guide](guide://project-management) (AI Collaboration context)
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
---
|
|
2
|
+
doc-type: guide
|
|
3
|
+
title: High-Level Troubleshooting Workflow
|
|
4
|
+
purpose: Documentation for ace-handbook/handbook/guides/debug-troubleshooting.g.md
|
|
5
|
+
ace-docs:
|
|
6
|
+
last-updated: 2026-01-08
|
|
7
|
+
last-checked: 2026-03-21
|
|
8
|
+
---
|
|
9
|
+
|
|
10
|
+
# High-Level Troubleshooting Workflow
|
|
11
|
+
|
|
12
|
+
This guide provides a general, technology-agnostic workflow for approaching development challenges, from initial
|
|
13
|
+
debugging to seeking help.
|
|
14
|
+
|
|
15
|
+
## Universal Troubleshooting Steps
|
|
16
|
+
|
|
17
|
+
| Step | What to do | Why |
|
|
18
|
+
|------|------------|-----|
|
|
19
|
+
| **1 Understand the system** | Skim docs/architecture first | You can’t debug what you don’t grasp. |
|
|
20
|
+
| **2 Make it fail on demand** | Reproduce the bug and minimise the input or scenario | Gives you a quick feedback loop & future test. |
|
|
21
|
+
| **3 Collect evidence** | Read stack traces, logs, error codes | Surface clues without touching code. |
|
|
22
|
+
| **4 Check recent changes/config** | Roll back toggles, feature flags, deployments | Regressions are usually fresh. |
|
|
23
|
+
| **5 Divide & conquer** | Bisect the call‑graph, comment blocks, or binary‑search commits | Narrows the suspect area fast. |
|
|
24
|
+
| **6 Form a hypothesis & probe** | Insert breakpoints/print‑debug, **do not "fix" yet** | Prevents cargo‑cult patches. |
|
|
25
|
+
| **7 Change one thing, re‑test** | One variable at a time, audit the steps | Keeps cause‑and‑effect clear. |
|
|
26
|
+
| **8 Validate & regress‑test** | Run the original minimal case + full suite | Confirms the root cause, avoids side‑effects. |
|
|
27
|
+
| **9 Document & share** | Note root cause, fix, follow‑ups | Future devs (and you) will thank you. |
|
|
28
|
+
| **10 Escalate or rubber‑duck** | Fresh eyes or an AI agent when stuck | External perspective breaks tunnel vision. |
|
|
29
|
+
|
|
30
|
+
## Elaborations on Key Steps
|
|
31
|
+
|
|
32
|
+
* **Step 2: Make it fail on demand:** This is crucial for effective testing. Aim for the *simplest possible*
|
|
33
|
+
reproducible case. This often forms the basis of a new regression test (see Step 8).
|
|
34
|
+
* **Step 3 & 4: Collect evidence & Check recent changes:** Don't underestimate logs, configuration files, and
|
|
35
|
+
recent commits (`git log`, `git blame`). Many issues are regressions introduced by recent changes.
|
|
36
|
+
* **Step 8: Validate & Regress-Test:** After applying a fix, *always* run the minimal failing case you created in
|
|
37
|
+
Step 2 to confirm the specific issue is resolved. Then, run the broader test suite (e.g., `bin/rspec`, `npm test`)
|
|
38
|
+
to check for unintended side-effects. Refer to the [Testing Guidelines Guide](testing.g.md) for more details.
|
|
39
|
+
* **Step 10: Escalate or Rubber Duck:** If you're stuck after diligently following the steps:
|
|
40
|
+
* **Rubber Ducking:** Explain the problem out loud (to yourself, a pet, or an inanimate object). This often
|
|
41
|
+
clarifies your thinking.
|
|
42
|
+
* **AI Assistance:** Consult an AI agent. Use structured prompts, providing the context (code, error, steps taken).
|
|
43
|
+
Reference the `[ask-an-agent workflow - PATH NEEDED]` for best practices.
|
|
44
|
+
* **Human Escalation:** If AI doesn't help, reach out to teammates. Prepare by summarizing the problem, what
|
|
45
|
+
you've tried (Steps 1-9), and specific questions. Check the `CONTRIBUTING.md` or team documentation for
|
|
46
|
+
preferred communication channels.
|
|
47
|
+
|
|
48
|
+
## Utilizing Documentation and Research
|
|
49
|
+
|
|
50
|
+
* **Internal Docs:** Before extensive debugging, always check project-specific documentation (`README.md`,
|
|
51
|
+
architecture diagrams in project docs, specific guides via `guide://` protocol).
|
|
52
|
+
* **External Research:** Use search engines effectively. Formulate precise queries including error messages,
|
|
53
|
+
technology names, and library versions.
|
|
54
|
+
|
|
55
|
+
## Language-Specific Considerations
|
|
56
|
+
|
|
57
|
+
While this guide provides a universal workflow, specific tools and techniques vary by language. For detailed
|
|
58
|
+
guidance, refer to the language-specific troubleshooting sections:
|
|
59
|
+
|
|
60
|
+
* [Ruby Troubleshooting](troubleshooting/ruby.md) (*To be created/moved from research*)
|
|
61
|
+
* [Rust Troubleshooting](troubleshooting/rust.md) (*To be created/moved from research*)
|
|
62
|
+
* [TypeScript Troubleshooting](troubleshooting/typescript.md) (*To be created/moved from research*)
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
# Ruby Error Handling Examples
|
|
2
|
+
|
|
3
|
+
This file provides Ruby-specific examples related to the main [Error Handling Guide](../error-handling.g.md).
|
|
4
|
+
|
|
5
|
+
* Mechanism: begin/rescue/ensure/raise
|
|
6
|
+
* Standard Library: StandardError hierarchy
|
|
7
|
+
|
|
8
|
+
```ruby
|
|
9
|
+
class CustomError < StandardError
|
|
10
|
+
attr_reader :context
|
|
11
|
+
|
|
12
|
+
def initialize(message = "Something went wrong", context = {})
|
|
13
|
+
super(message)
|
|
14
|
+
@context = context
|
|
15
|
+
end
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
begin
|
|
19
|
+
# Code that might raise an error
|
|
20
|
+
raise CustomError.new("Failed operation", { data: 'example' }) if some_condition
|
|
21
|
+
rescue CustomError => e
|
|
22
|
+
puts "Caught custom error: #{e.message}, Context: #{e.context}"
|
|
23
|
+
rescue StandardError => e
|
|
24
|
+
puts "Caught other standard error: #{e.message}"
|
|
25
|
+
ensure
|
|
26
|
+
# Cleanup code
|
|
27
|
+
puts "Ensuring cleanup"
|
|
28
|
+
end
|
|
29
|
+
```
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
# Rust Error Handling Examples
|
|
2
|
+
|
|
3
|
+
This file provides Rust-specific examples and considerations related to the main [Error Handling Guide](../error-handling.g.md).
|
|
4
|
+
|
|
5
|
+
* **Mechanisms:** `Result<T, E>` enum for recoverable errors, `panic!` macro for unrecoverable errors.
|
|
6
|
+
* **Libraries:** `thiserror`, `anyhow` for custom error types and convenience.
|
|
7
|
+
|
|
8
|
+
```rust
|
|
9
|
+
use std::fmt;
|
|
10
|
+
|
|
11
|
+
// Example using standard library Result and Box<dyn Error>
|
|
12
|
+
fn do_something(input: &str) -> Result<String, Box<dyn std::error::Error>> {
|
|
13
|
+
if input.is_empty() {
|
|
14
|
+
return Err("Input cannot be empty".into()); // Simple error conversion
|
|
15
|
+
}
|
|
16
|
+
// ... potentially complex logic ...
|
|
17
|
+
Ok(format!("Processed {}", input))
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
// Example custom error enum (could use 'thiserror' crate for convenience)
|
|
21
|
+
#[derive(Debug)]
|
|
22
|
+
enum ProcessingError {
|
|
23
|
+
InvalidInput(String),
|
|
24
|
+
InternalError(String),
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
impl fmt::Display for ProcessingError {
|
|
28
|
+
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
|
29
|
+
match self {
|
|
30
|
+
ProcessingError::InvalidInput(msg) => write!(f, "Invalid Input: {}", msg),
|
|
31
|
+
ProcessingError::InternalError(msg) => write!(f, "Internal Error: {}", msg),
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
impl std::error::Error for ProcessingError {}
|
|
37
|
+
|
|
38
|
+
fn do_something_custom(input: &str) -> Result<String, ProcessingError> {
|
|
39
|
+
if input.is_empty() {
|
|
40
|
+
return Err(ProcessingError::InvalidInput("Input was empty".to_string()));
|
|
41
|
+
}
|
|
42
|
+
// ...
|
|
43
|
+
Ok(format!("Processed {}", input))
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
fn main() {
|
|
47
|
+
match do_something_custom("") {
|
|
48
|
+
Ok(result) => println!("Success: {}", result),
|
|
49
|
+
Err(e) => println!("Error: {}", e),
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
// Example of propagating errors with `?` operator
|
|
53
|
+
let result = do_something_custom("valid").expect("Should succeed");
|
|
54
|
+
println!("Result via expect: {}", result);
|
|
55
|
+
|
|
56
|
+
// Panics for unrecoverable errors (use sparingly)
|
|
57
|
+
// panic!("This is an unrecoverable error!");
|
|
58
|
+
}
|
|
59
|
+
```
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
# TypeScript Error Handling Examples
|
|
2
|
+
|
|
3
|
+
This file provides TypeScript-specific examples related to the main [Error Handling Guide](../error-handling.g.md).
|
|
4
|
+
|
|
5
|
+
* **Mechanism:** try/catch/finally/throw
|
|
6
|
+
* **Custom Errors:** Extend the built-in Error class.
|
|
7
|
+
|
|
8
|
+
```typescript
|
|
9
|
+
class CustomError extends Error {
|
|
10
|
+
context: Record<string, any>;
|
|
11
|
+
|
|
12
|
+
constructor(message: string, context: Record<string, any> = {}) {
|
|
13
|
+
super(message);
|
|
14
|
+
this.name = 'CustomError'; // Important for identifying error type
|
|
15
|
+
this.context = context;
|
|
16
|
+
// Ensure the prototype chain is set correctly
|
|
17
|
+
Object.setPrototypeOf(this, CustomError.prototype);
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
try {
|
|
22
|
+
// Code that might throw an error
|
|
23
|
+
if (someCondition) {
|
|
24
|
+
throw new CustomError('Failed operation', { data: 'example' });
|
|
25
|
+
}
|
|
26
|
+
} catch (error) {
|
|
27
|
+
if (error instanceof CustomError) {
|
|
28
|
+
console.error(`Caught custom error: ${error.message}, Context:`, error.context);
|
|
29
|
+
} else if (error instanceof Error) {
|
|
30
|
+
console.error(`Caught other error: ${error.message}`);
|
|
31
|
+
} else {
|
|
32
|
+
console.error('Caught unknown error:', error);
|
|
33
|
+
}
|
|
34
|
+
} finally {
|
|
35
|
+
// Cleanup code
|
|
36
|
+
console.log('Ensuring cleanup');
|
|
37
|
+
}
|
|
38
|
+
```
|
|
@@ -0,0 +1,207 @@
|
|
|
1
|
+
---
|
|
2
|
+
doc-type: guide
|
|
3
|
+
title: Error Handling Guidelines
|
|
4
|
+
purpose: Documentation for ace-handbook/handbook/guides/error-handling.g.md
|
|
5
|
+
ace-docs:
|
|
6
|
+
last-updated: 2026-01-08
|
|
7
|
+
last-checked: 2026-03-21
|
|
8
|
+
---
|
|
9
|
+
|
|
10
|
+
# Error Handling Guidelines
|
|
11
|
+
|
|
12
|
+
## Goal
|
|
13
|
+
|
|
14
|
+
This guide outlines the fundamental principles and standards for handling errors consistently and effectively
|
|
15
|
+
throughout the project, ensuring robustness, debuggability, and a good user experience.
|
|
16
|
+
|
|
17
|
+
## Exception Hierarchy
|
|
18
|
+
|
|
19
|
+
Establish a clear hierarchy for custom exceptions or error types specific to your application or
|
|
20
|
+
library. This allows for more granular error handling.
|
|
21
|
+
|
|
22
|
+
- Define a base error class/type for your application (e.g., `MyAppError`).
|
|
23
|
+
- Create specific error subclasses that inherit from the base error (e.g., `ConfigurationError`, `ApiError`, `DatabaseError`).
|
|
24
|
+
- Include relevant context within your error objects (see 'Rich Context' below).
|
|
25
|
+
|
|
26
|
+
```javascript
|
|
27
|
+
// Pseudo-code example hierarchy
|
|
28
|
+
class MyAppError extends Error {}
|
|
29
|
+
class ConfigurationError extends MyAppError {}
|
|
30
|
+
class AgentError extends MyAppError {
|
|
31
|
+
constructor(message, context = {}) {
|
|
32
|
+
super(message);
|
|
33
|
+
this.context = context;
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
class ToolError extends MyAppError {}
|
|
37
|
+
class ExternalServiceError extends MyAppError {
|
|
38
|
+
constructor(message, requestId = null) {
|
|
39
|
+
super(message);
|
|
40
|
+
this.requestId = requestId;
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
## Best Practices
|
|
46
|
+
|
|
47
|
+
1. **Rich Context**:
|
|
48
|
+
When catching and logging errors, include as much relevant context as possible without logging sensitive data.
|
|
49
|
+
This aids debugging.
|
|
50
|
+
|
|
51
|
+
```javascript
|
|
52
|
+
// Pseudo-code example
|
|
53
|
+
try {
|
|
54
|
+
agent.execute(task);
|
|
55
|
+
} catch (error) {
|
|
56
|
+
if (error instanceof AgentError) {
|
|
57
|
+
logger.error("Agent execution failed", {
|
|
58
|
+
errorMessage: error.message,
|
|
59
|
+
errorContext: error.context,
|
|
60
|
+
stackTrace: error.stack.substring(0, 500) // Log part of the stack
|
|
61
|
+
});
|
|
62
|
+
} else {
|
|
63
|
+
logger.error("Unexpected error during agent execution", {
|
|
64
|
+
errorMessage: error.message,
|
|
65
|
+
stackTrace: error.stack.substring(0, 500)
|
|
66
|
+
});
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
```
|
|
70
|
+
|
|
71
|
+
2. **Recovery Strategies**:
|
|
72
|
+
Implement strategies to recover from transient errors, especially network-related issues.
|
|
73
|
+
|
|
74
|
+
```javascript
|
|
75
|
+
// Pseudo-code example: Retry with exponential backoff
|
|
76
|
+
function executeWithRetry(task) {
|
|
77
|
+
let retries = 0;
|
|
78
|
+
const maxRetries = 3;
|
|
79
|
+
while (true) {
|
|
80
|
+
try {
|
|
81
|
+
return agent.execute(task);
|
|
82
|
+
} catch (error) {
|
|
83
|
+
if (error instanceof ExternalServiceError && retries < maxRetries) {
|
|
84
|
+
retries++;
|
|
85
|
+
const delay = Math.pow(2, retries) * 1000; // Exponential backoff
|
|
86
|
+
sleep(delay);
|
|
87
|
+
} else {
|
|
88
|
+
throw error; // Re-throw if max retries reached or not a recoverable error
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
```
|
|
94
|
+
|
|
95
|
+
3. **Clean Resource Management**:
|
|
96
|
+
Ensure resources (files, network connections, locks) are properly released, even if errors occur. Use
|
|
97
|
+
`try...finally` or equivalent language constructs (like Python\'s `with` statement or Go\'s `defer`).
|
|
98
|
+
|
|
99
|
+
```javascript
|
|
100
|
+
// Pseudo-code example
|
|
101
|
+
let resource = acquireResource();
|
|
102
|
+
try {
|
|
103
|
+
// Use the resource
|
|
104
|
+
yield resource;
|
|
105
|
+
} finally {
|
|
106
|
+
releaseResource(resource);
|
|
107
|
+
}
|
|
108
|
+
```
|
|
109
|
+
|
|
110
|
+
## Debugging Guide
|
|
111
|
+
|
|
112
|
+
## Advanced Error Handling Patterns
|
|
113
|
+
|
|
114
|
+
Consider these patterns for more robust applications:
|
|
115
|
+
|
|
116
|
+
- **Structured Error Objects:** Define custom error classes/types that include relevant context (e.g., status codes,
|
|
117
|
+
internal error codes, request IDs). This helps in programmatic error handling and monitoring.
|
|
118
|
+
|
|
119
|
+
```javascript
|
|
120
|
+
// Pseudo-code example
|
|
121
|
+
class ApiError extends Error {
|
|
122
|
+
constructor(message, { statusCode = 500, errorCode = 'UNKNOWN', details = {} } = {}) {
|
|
123
|
+
super(message);
|
|
124
|
+
this.statusCode = statusCode;
|
|
125
|
+
this.errorCode = errorCode;
|
|
126
|
+
this.details = details;
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
// Example usage:
|
|
130
|
+
// throw new ApiError("User not found", { statusCode: 404, errorCode: 'USER_NOT_FOUND', details: { userId: id } });
|
|
131
|
+
```
|
|
132
|
+
|
|
133
|
+
- **Error Categorization:** Distinguish between:
|
|
134
|
+
- **Operational Errors:** Expected issues (e.g., invalid input, resource not found) that can often be handled
|
|
135
|
+
gracefully.
|
|
136
|
+
- **Programming Errors:** Bugs in the code that need fixing (e.g., type errors, null references).
|
|
137
|
+
- **System Errors:** External issues (e.g., database unavailable, network failure).
|
|
138
|
+
- **Recovery Strategies:** Implement strategies for transient failures:
|
|
139
|
+
- **Retry with Backoff:** Automatically retry failed operations (especially network requests) with increasing
|
|
140
|
+
delays.
|
|
141
|
+
- **Circuit Breaker:** Prevent repeated calls to a failing service by temporarily blocking
|
|
142
|
+
requests after a certain number of failures.
|
|
143
|
+
- **Fallbacks:** Provide a degraded but functional experience if a primary operation
|
|
144
|
+
fails (e.g., return cached data if a live fetch fails).
|
|
145
|
+
- **Contextual Logging:** Ensure logs capture sufficient context (user ID, request ID,
|
|
146
|
+
operation parameters) to diagnose errors effectively, while avoiding sensitive data.
|
|
147
|
+
|
|
148
|
+
1. **Enable Debug Logging**:
|
|
149
|
+
Configure your application\'s logger to output detailed debug messages when needed.
|
|
150
|
+
This often involves setting a log level via configuration.
|
|
151
|
+
|
|
152
|
+
```javascript
|
|
153
|
+
// Example: Conceptual configuration
|
|
154
|
+
MyApp.configure({
|
|
155
|
+
logLevel: 'debug', // Or 'info', 'warn', 'error'
|
|
156
|
+
logFormatter: (severity, timestamp, message) => {
|
|
157
|
+
return `[${timestamp}] ${severity.toUpperCase()}: ${message}`;
|
|
158
|
+
}
|
|
159
|
+
});
|
|
160
|
+
```
|
|
161
|
+
|
|
162
|
+
2. **Inspect State**:
|
|
163
|
+
Provide mechanisms to inspect the internal state of key components during debugging, if feasible and safe.
|
|
164
|
+
|
|
165
|
+
```javascript
|
|
166
|
+
// Example: Conceptual methods (actual implementation depends on language/design)
|
|
167
|
+
let debugInfo = agent.getDebugInfo();
|
|
168
|
+
let trace = agent.getExecutionTrace();
|
|
169
|
+
```
|
|
170
|
+
|
|
171
|
+
3. **Common Issues**:
|
|
172
|
+
|
|
173
|
+
- LLM timeouts: Check network and retry settings
|
|
174
|
+
- Memory issues: Review resource cleanup
|
|
175
|
+
- Thread deadlocks: Check lock ordering
|
|
176
|
+
|
|
177
|
+
## Error Context
|
|
178
|
+
|
|
179
|
+
Always include relevant context when raising or logging errors. This aids debugging significantly.
|
|
180
|
+
|
|
181
|
+
**Good Context:**
|
|
182
|
+
|
|
183
|
+
```plaintext
|
|
184
|
+
// Log the error with context
|
|
185
|
+
logError(\"Failed to process user data\", error, { userId: 123, operation: \'updateProfile\' });
|
|
186
|
+
|
|
187
|
+
// Raise error with context
|
|
188
|
+
throw new UserProcessingError(\"Failed to update profile for user 123\", { originalError: error, userId: 123 });
|
|
189
|
+
```
|
|
190
|
+
|
|
191
|
+
**Avoid Generic Messages:**
|
|
192
|
+
|
|
193
|
+
```plaintext
|
|
194
|
+
// Less helpful
|
|
195
|
+
logError("An error occurred", error);
|
|
196
|
+
throw new Error("Something went wrong");
|
|
197
|
+
```
|
|
198
|
+
|
|
199
|
+
## Language/Environment-Specific Examples
|
|
200
|
+
|
|
201
|
+
For specific code examples demonstrating error handling patterns, custom error classes, or library integrations
|
|
202
|
+
in different languages (e.g., Ruby\'s `begin/rescue`, Python\'s `try/except`, JavaScript\'s `try/catch`,
|
|
203
|
+
|
|
204
|
+
## Related Documentation
|
|
205
|
+
|
|
206
|
+
- [Coding Standards](./coding-standards.g.md)
|
|
207
|
+
- [Quality Assurance](./quality-assurance.g.md) (Logging, Monitoring)
|