red64-cli 0.3.0 → 0.6.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 (95) hide show
  1. package/README.md +194 -338
  2. package/dist/cli/parseArgs.d.ts.map +1 -1
  3. package/dist/cli/parseArgs.js +5 -13
  4. package/dist/cli/parseArgs.js.map +1 -1
  5. package/dist/components/init/types.d.ts +0 -2
  6. package/dist/components/init/types.d.ts.map +1 -1
  7. package/dist/components/screens/HelpScreen.d.ts.map +1 -1
  8. package/dist/components/screens/HelpScreen.js +0 -2
  9. package/dist/components/screens/HelpScreen.js.map +1 -1
  10. package/dist/components/screens/InitScreen.d.ts.map +1 -1
  11. package/dist/components/screens/InitScreen.js +5 -8
  12. package/dist/components/screens/InitScreen.js.map +1 -1
  13. package/dist/components/screens/StartScreen.d.ts.map +1 -1
  14. package/dist/components/screens/StartScreen.js +29 -8
  15. package/dist/components/screens/StartScreen.js.map +1 -1
  16. package/dist/components/screens/StatusScreen.d.ts.map +1 -1
  17. package/dist/components/screens/StatusScreen.js +16 -1
  18. package/dist/components/screens/StatusScreen.js.map +1 -1
  19. package/dist/services/AgentInvoker.d.ts.map +1 -1
  20. package/dist/services/AgentInvoker.js +76 -37
  21. package/dist/services/AgentInvoker.js.map +1 -1
  22. package/dist/services/ClaudeErrorDetector.d.ts +1 -1
  23. package/dist/services/ClaudeErrorDetector.d.ts.map +1 -1
  24. package/dist/services/ClaudeErrorDetector.js +1 -0
  25. package/dist/services/ClaudeErrorDetector.js.map +1 -1
  26. package/dist/services/ClaudeHealthCheck.d.ts +7 -0
  27. package/dist/services/ClaudeHealthCheck.d.ts.map +1 -1
  28. package/dist/services/ClaudeHealthCheck.js +76 -12
  29. package/dist/services/ClaudeHealthCheck.js.map +1 -1
  30. package/dist/services/ConfigService.d.ts +1 -0
  31. package/dist/services/ConfigService.d.ts.map +1 -1
  32. package/dist/services/ConfigService.js.map +1 -1
  33. package/dist/services/DockerRunner.js +1 -1
  34. package/dist/services/DockerRunner.js.map +1 -1
  35. package/dist/services/PhaseExecutor.d.ts.map +1 -1
  36. package/dist/services/PhaseExecutor.js +2 -1
  37. package/dist/services/PhaseExecutor.js.map +1 -1
  38. package/dist/services/TaskRunner.d.ts.map +1 -1
  39. package/dist/services/TaskRunner.js +2 -1
  40. package/dist/services/TaskRunner.js.map +1 -1
  41. package/dist/services/index.d.ts +1 -1
  42. package/dist/services/index.d.ts.map +1 -1
  43. package/dist/services/index.js +1 -1
  44. package/dist/services/index.js.map +1 -1
  45. package/dist/types/index.d.ts +4 -3
  46. package/dist/types/index.d.ts.map +1 -1
  47. package/dist/types/index.js.map +1 -1
  48. package/framework/stacks/c/code-quality.md +326 -0
  49. package/framework/stacks/c/coding-style.md +347 -0
  50. package/framework/stacks/c/conventions.md +513 -0
  51. package/framework/stacks/c/error-handling.md +350 -0
  52. package/framework/stacks/c/feedback.md +158 -0
  53. package/framework/stacks/c/memory-safety.md +408 -0
  54. package/framework/stacks/c/tech.md +122 -0
  55. package/framework/stacks/c/testing.md +472 -0
  56. package/framework/stacks/cpp/code-quality.md +282 -0
  57. package/framework/stacks/cpp/coding-style.md +363 -0
  58. package/framework/stacks/cpp/conventions.md +420 -0
  59. package/framework/stacks/cpp/error-handling.md +264 -0
  60. package/framework/stacks/cpp/feedback.md +104 -0
  61. package/framework/stacks/cpp/memory-safety.md +351 -0
  62. package/framework/stacks/cpp/tech.md +160 -0
  63. package/framework/stacks/cpp/testing.md +323 -0
  64. package/framework/stacks/java/code-quality.md +357 -0
  65. package/framework/stacks/java/coding-style.md +400 -0
  66. package/framework/stacks/java/conventions.md +437 -0
  67. package/framework/stacks/java/error-handling.md +408 -0
  68. package/framework/stacks/java/feedback.md +180 -0
  69. package/framework/stacks/java/tech.md +126 -0
  70. package/framework/stacks/java/testing.md +485 -0
  71. package/framework/stacks/javascript/async-patterns.md +216 -0
  72. package/framework/stacks/javascript/code-quality.md +182 -0
  73. package/framework/stacks/javascript/coding-style.md +293 -0
  74. package/framework/stacks/javascript/conventions.md +268 -0
  75. package/framework/stacks/javascript/error-handling.md +216 -0
  76. package/framework/stacks/javascript/feedback.md +80 -0
  77. package/framework/stacks/javascript/tech.md +114 -0
  78. package/framework/stacks/javascript/testing.md +209 -0
  79. package/framework/stacks/loco/code-quality.md +156 -0
  80. package/framework/stacks/loco/coding-style.md +247 -0
  81. package/framework/stacks/loco/error-handling.md +225 -0
  82. package/framework/stacks/loco/feedback.md +35 -0
  83. package/framework/stacks/loco/loco.md +342 -0
  84. package/framework/stacks/loco/structure.md +193 -0
  85. package/framework/stacks/loco/tech.md +129 -0
  86. package/framework/stacks/loco/testing.md +211 -0
  87. package/framework/stacks/rust/code-quality.md +370 -0
  88. package/framework/stacks/rust/coding-style.md +475 -0
  89. package/framework/stacks/rust/conventions.md +430 -0
  90. package/framework/stacks/rust/error-handling.md +399 -0
  91. package/framework/stacks/rust/feedback.md +152 -0
  92. package/framework/stacks/rust/memory-safety.md +398 -0
  93. package/framework/stacks/rust/tech.md +121 -0
  94. package/framework/stacks/rust/testing.md +528 -0
  95. package/package.json +14 -2
@@ -0,0 +1,420 @@
1
+ # Development Conventions
2
+
3
+ General development practices, workflow, and operational standards for C++ projects.
4
+
5
+ ---
6
+
7
+ ## Philosophy
8
+
9
+ - **Predictable process**: Consistent workflows reduce friction and errors
10
+ - **Automated enforcement**: clang-tidy and CI catch what humans miss
11
+ - **Build reproducibility**: Lock dependencies, pin toolchains, use presets
12
+ - **Documentation as code**: Keep docs next to the code they describe
13
+
14
+ ---
15
+
16
+ ## Git Workflow
17
+
18
+ ### Branch Strategy
19
+
20
+ ```
21
+ main # Production-ready, always builds
22
+ |-- feat/... # Feature branches (short-lived)
23
+ |-- fix/... # Bug fix branches
24
+ |-- chore/... # Maintenance, dependency updates
25
+ ```
26
+
27
+ ### Branch Naming
28
+
29
+ ```bash
30
+ feat/add-user-authentication
31
+ fix/buffer-overflow-in-parser
32
+ chore/upgrade-fmt-to-11
33
+ refactor/extract-http-client
34
+ ```
35
+
36
+ **Pattern**: `{type}/{short-description}` with lowercase and hyphens.
37
+
38
+ ### Workflow
39
+
40
+ 1. Create branch from `main`
41
+ 2. Make small, focused commits
42
+ 3. Open PR when ready for review
43
+ 4. Squash merge into `main`
44
+ 5. Delete branch after merge
45
+
46
+ ---
47
+
48
+ ## Commit Conventions
49
+
50
+ ### Conventional Commits
51
+
52
+ ```
53
+ feat: add JWT authentication middleware
54
+ fix: prevent buffer overflow in JSON parser
55
+ refactor: extract HTTP client into separate library
56
+ test: add parameterized tests for email validation
57
+ docs: update CMake build instructions
58
+ chore: upgrade vcpkg baseline to 2025.01
59
+ ci: add ASan/UBSan to test matrix
60
+ perf: use string_view to avoid copies in request parsing
61
+ ```
62
+
63
+ ### Format
64
+
65
+ ```
66
+ {type}: {short description}
67
+
68
+ {optional body explaining why, not what}
69
+
70
+ {optional footer: BREAKING CHANGE, Closes #123}
71
+ ```
72
+
73
+ ### Types
74
+
75
+ | Type | Description |
76
+ |---|---|
77
+ | `feat` | New feature or capability |
78
+ | `fix` | Bug fix |
79
+ | `refactor` | Code change that neither fixes nor adds |
80
+ | `test` | Adding or updating tests |
81
+ | `docs` | Documentation only |
82
+ | `chore` | Maintenance, dependencies, tooling |
83
+ | `ci` | CI/CD configuration changes |
84
+ | `perf` | Performance improvement |
85
+
86
+ **Rule**: One logical change per commit. If the commit message needs "and", split it.
87
+
88
+ ---
89
+
90
+ ## CMake Project Structure
91
+
92
+ ### Standard Layout
93
+
94
+ ```
95
+ myproject/
96
+ CMakeLists.txt # Root CMakeLists
97
+ CMakePresets.json # Build presets
98
+ vcpkg.json # Dependency manifest
99
+ .clang-format # Formatting config
100
+ .clang-tidy # Static analysis config
101
+ cmake/
102
+ CompilerWarnings.cmake # Shared warning flags
103
+ Sanitizers.cmake # Sanitizer build options
104
+ include/
105
+ myproject/ # Public headers
106
+ user_service.hpp
107
+ http_client.hpp
108
+ src/
109
+ user_service.cpp
110
+ http_client.cpp
111
+ main.cpp
112
+ tests/
113
+ CMakeLists.txt
114
+ unit/
115
+ test_user_service.cpp
116
+ integration/
117
+ test_database.cpp
118
+ benchmark/
119
+ bench_serialization.cpp
120
+ docs/
121
+ third_party/ # Vendored dependencies (if any)
122
+ ```
123
+
124
+ ### CMakePresets.json
125
+
126
+ ```json
127
+ {
128
+ "version": 6,
129
+ "configurePresets": [
130
+ {
131
+ "name": "default",
132
+ "binaryDir": "${sourceDir}/build",
133
+ "generator": "Ninja",
134
+ "cacheVariables": {
135
+ "CMAKE_CXX_STANDARD": "23",
136
+ "CMAKE_EXPORT_COMPILE_COMMANDS": "ON"
137
+ },
138
+ "toolchainFile": "$env{VCPKG_ROOT}/scripts/buildsystems/vcpkg.cmake"
139
+ },
140
+ {
141
+ "name": "debug",
142
+ "inherits": "default",
143
+ "cacheVariables": {
144
+ "CMAKE_BUILD_TYPE": "Debug"
145
+ }
146
+ },
147
+ {
148
+ "name": "release",
149
+ "inherits": "default",
150
+ "cacheVariables": {
151
+ "CMAKE_BUILD_TYPE": "Release"
152
+ }
153
+ },
154
+ {
155
+ "name": "asan",
156
+ "inherits": "debug",
157
+ "cacheVariables": {
158
+ "CMAKE_CXX_FLAGS": "-fsanitize=address,undefined -fno-omit-frame-pointer"
159
+ }
160
+ }
161
+ ],
162
+ "buildPresets": [
163
+ {"name": "default", "configurePreset": "default"},
164
+ {"name": "release", "configurePreset": "release"},
165
+ {"name": "asan", "configurePreset": "asan"}
166
+ ],
167
+ "testPresets": [
168
+ {
169
+ "name": "default",
170
+ "configurePreset": "default",
171
+ "output": {"outputOnFailure": true}
172
+ }
173
+ ]
174
+ }
175
+ ```
176
+
177
+ ---
178
+
179
+ ## Dependency Management
180
+
181
+ ### vcpkg Manifest Mode (Preferred)
182
+
183
+ ```json
184
+ {
185
+ "name": "myproject",
186
+ "version-string": "1.0.0",
187
+ "dependencies": [
188
+ "fmt",
189
+ "spdlog",
190
+ "nlohmann-json",
191
+ "gtest",
192
+ "benchmark"
193
+ ],
194
+ "builtin-baseline": "a1a1cbc975e450accd1f5b7e4530e1378575f291"
195
+ }
196
+ ```
197
+
198
+ ```bash
199
+ # Add a dependency
200
+ vcpkg add port abseil
201
+
202
+ # Update baseline (all dependencies)
203
+ vcpkg x-update-baseline
204
+ ```
205
+
206
+ ### Dependency Rules
207
+
208
+ - Use manifest mode (`vcpkg.json`), not classic mode
209
+ - Pin the baseline hash in `vcpkg.json`
210
+ - Update baseline regularly (monthly or per sprint)
211
+ - Prefer header-only libraries when performance permits
212
+ - Vendor critical dependencies only as a last resort
213
+
214
+ ---
215
+
216
+ ## Header vs Source Organization
217
+
218
+ ### Public vs Private Headers
219
+
220
+ ```
221
+ include/myproject/ # Public API headers (installed with library)
222
+ user_service.hpp # Declarations only, minimal includes
223
+ src/
224
+ user_service.cpp # Implementations
225
+ internal/ # Private headers (not installed)
226
+ database_impl.hpp
227
+ ```
228
+
229
+ ### Include Guard Style
230
+
231
+ ```cpp
232
+ // GOOD: #pragma once (widely supported, no name collisions)
233
+ #pragma once
234
+
235
+ #include <string>
236
+ #include <vector>
237
+
238
+ namespace myproject {
239
+ class UserService { /* ... */ };
240
+ } // namespace myproject
241
+ ```
242
+
243
+ ```cpp
244
+ // ACCEPTABLE: Traditional include guards (required for some compilers)
245
+ #ifndef MYPROJECT_USER_SERVICE_HPP
246
+ #define MYPROJECT_USER_SERVICE_HPP
247
+
248
+ // ...
249
+
250
+ #endif // MYPROJECT_USER_SERVICE_HPP
251
+ ```
252
+
253
+ **Preference**: Use `#pragma once` unless the project must support exotic compilers.
254
+
255
+ ### Include Order
256
+
257
+ ```cpp
258
+ // 1. Corresponding header (for .cpp files)
259
+ #include "myproject/user_service.hpp"
260
+
261
+ // 2. C++ standard library
262
+ #include <algorithm>
263
+ #include <string>
264
+ #include <vector>
265
+
266
+ // 3. Third-party libraries
267
+ #include <fmt/core.h>
268
+ #include <spdlog/spdlog.h>
269
+ #include <nlohmann/json.hpp>
270
+
271
+ // 4. Project headers
272
+ #include "myproject/database.hpp"
273
+ #include "myproject/error.hpp"
274
+ ```
275
+
276
+ ---
277
+
278
+ ## Logging with spdlog
279
+
280
+ ### Setup
281
+
282
+ ```cpp
283
+ #include <spdlog/spdlog.h>
284
+ #include <spdlog/sinks/stdout_color_sinks.h>
285
+ #include <spdlog/sinks/rotating_file_sink.h>
286
+
287
+ void init_logging() {
288
+ auto console = std::make_shared<spdlog::sinks::stdout_color_sink_mt>();
289
+ auto file = std::make_shared<spdlog::sinks::rotating_file_sink_mt>(
290
+ "logs/app.log", 1024 * 1024 * 5, 3);
291
+
292
+ auto logger = std::make_shared<spdlog::logger>(
293
+ "app", spdlog::sinks_init_list{console, file});
294
+ logger->set_level(spdlog::level::info);
295
+ logger->set_pattern("[%Y-%m-%d %H:%M:%S.%e] [%^%l%$] [%t] %v");
296
+ spdlog::set_default_logger(logger);
297
+ }
298
+ ```
299
+
300
+ ### Usage
301
+
302
+ ```cpp
303
+ // GOOD: Structured key-value logging with fmt syntax
304
+ spdlog::info("user_created id={} email={}", user.id(), user.email());
305
+ spdlog::warn("retry_attempt service={} attempt={}/{}", "payment", attempt, max);
306
+ spdlog::error("operation_failed reason={}", error.message());
307
+
308
+ // BAD: Unstructured string concatenation
309
+ spdlog::info("User " + name + " was created");
310
+ ```
311
+
312
+ ### Log Levels
313
+
314
+ | Level | Use Case |
315
+ |---|---|
316
+ | `trace` | Fine-grained debug detail (disabled in production) |
317
+ | `debug` | Development diagnostics |
318
+ | `info` | Normal operations (request handled, service started) |
319
+ | `warn` | Recoverable issues (retry succeeded, deprecated usage) |
320
+ | `error` | Failed operations (connection lost, invalid response) |
321
+ | `critical` | System unusable (out of memory, data corruption) |
322
+
323
+ ---
324
+
325
+ ## Documentation Standards
326
+
327
+ ### Doxygen-Style Comments
328
+
329
+ ```cpp
330
+ /// @brief Create a new user account.
331
+ ///
332
+ /// Validates email uniqueness and hashes the password before
333
+ /// persisting to the database.
334
+ ///
335
+ /// @param request Validated user creation request.
336
+ /// @return The created User, or an error if email is taken.
337
+ /// @see UserRepo::save
338
+ [[nodiscard]] Result<User> create_user(const CreateRequest& request);
339
+ ```
340
+
341
+ ### When to Write Documentation
342
+
343
+ | Element | Documentation Required? |
344
+ |---|---|
345
+ | Public class | Yes |
346
+ | Public function/method | Yes |
347
+ | Private function | Only if non-obvious |
348
+ | Test functions | No (test name is the doc) |
349
+ | Template parameters | Yes, describe constraints |
350
+
351
+ ### Inline Comments
352
+
353
+ ```cpp
354
+ // GOOD: Explain WHY, not what
355
+ // Rate limit to 5/min to prevent brute force attacks
356
+ constexpr int kMaxAuthAttemptsPerMinute = 5;
357
+
358
+ // BAD: Restates the code
359
+ // Set max to 5
360
+ constexpr int kMax = 5;
361
+ ```
362
+
363
+ ---
364
+
365
+ ## PR Review Checklist
366
+
367
+ ### Author Checklist (Before Requesting Review)
368
+
369
+ - [ ] Tests pass locally (`ctest --test-dir build`)
370
+ - [ ] clang-tidy passes (`run-clang-tidy -p build`)
371
+ - [ ] clang-format applied (`clang-format -i ...`)
372
+ - [ ] No compiler warnings with `-Wall -Wextra -Werror`
373
+ - [ ] New features have tests
374
+ - [ ] No secrets or credentials committed
375
+ - [ ] PR description explains WHY, not just what
376
+
377
+ ### Reviewer Checklist
378
+
379
+ - [ ] Code follows project conventions
380
+ - [ ] Error cases are handled (expected/exceptions)
381
+ - [ ] No raw owning pointers, manual new/delete
382
+ - [ ] No unnecessary copies (use references, string_view, span)
383
+ - [ ] Thread safety considered for shared data
384
+ - [ ] Tests cover happy path and edge cases
385
+
386
+ ---
387
+
388
+ ## .gitignore
389
+
390
+ ```gitignore
391
+ # Build artifacts
392
+ build/
393
+ build-*/
394
+ out/
395
+
396
+ # IDE
397
+ .vscode/settings.json
398
+ .idea/
399
+ *.swp
400
+ *~
401
+
402
+ # vcpkg
403
+ vcpkg_installed/
404
+
405
+ # Coverage
406
+ *.gcda
407
+ *.gcno
408
+ coverage-report/
409
+
410
+ # Compiled objects
411
+ *.o
412
+ *.obj
413
+ *.a
414
+ *.so
415
+ *.dylib
416
+ ```
417
+
418
+ ---
419
+
420
+ _Conventions reduce cognitive load. Follow them consistently so the team can focus on solving problems, not debating style._
@@ -0,0 +1,264 @@
1
+ # Error Handling Patterns
2
+
3
+ Structured error handling for modern C++ with std::expected (C++23), exceptions, and RAII.
4
+
5
+ ---
6
+
7
+ ## Philosophy
8
+
9
+ - **Fail fast**: Validate inputs early, return errors immediately on invalid state
10
+ - **Make errors visible**: Use types that force callers to handle failure
11
+ - **RAII for cleanup**: Never write manual cleanup code; destructors handle it
12
+ - **Pick one strategy per layer**: Do not mix exceptions and error codes in the same API surface
13
+ - **Ref**: C++ Core Guidelines E.1-E.31
14
+
15
+ ---
16
+
17
+ ## Exception Safety Guarantees
18
+
19
+ Every function provides one of these guarantees. Document which one.
20
+
21
+ | Guarantee | Description | Example |
22
+ |---|---|---|
23
+ | **Nothrow** | Never throws. Marked `noexcept`. | Destructors, swap, move operations |
24
+ | **Strong** | If an exception is thrown, state rolls back to before the call. | Copy-and-swap idiom |
25
+ | **Basic** | If an exception is thrown, no resources leak and invariants hold. Objects may be in a valid but unspecified state. | Most standard library operations |
26
+
27
+ ```cpp
28
+ // Nothrow guarantee: destructors, move operations (CG: C.66, C.85)
29
+ class Connection {
30
+ public:
31
+ ~Connection() noexcept;
32
+ Connection(Connection&& other) noexcept;
33
+ Connection& operator=(Connection&& other) noexcept;
34
+ };
35
+
36
+ // Strong guarantee via copy-and-swap (CG: C.83)
37
+ class UserList {
38
+ public:
39
+ UserList& operator=(UserList other) noexcept { // Pass by value = copy
40
+ swap(*this, other); // noexcept swap
41
+ return *this;
42
+ }
43
+
44
+ friend void swap(UserList& a, UserList& b) noexcept {
45
+ using std::swap;
46
+ swap(a.users_, b.users_);
47
+ }
48
+
49
+ private:
50
+ std::vector<User> users_;
51
+ };
52
+ ```
53
+
54
+ ---
55
+
56
+ ## std::expected (C++23) -- Preferred for Recoverable Errors
57
+
58
+ `std::expected<T, E>` returns either a value of type `T` or an error of type `E`. No stack unwinding, no hidden control flow.
59
+
60
+ ### Error Type Definition
61
+
62
+ ```cpp
63
+ // error.hpp
64
+ #include <string>
65
+ #include <expected>
66
+
67
+ enum class ErrorCode {
68
+ kNotFound,
69
+ kAlreadyExists,
70
+ kUnauthorized,
71
+ kValidation,
72
+ kInternal,
73
+ kTimeout,
74
+ };
75
+
76
+ struct Error {
77
+ ErrorCode code;
78
+ std::string message;
79
+ std::string context; // Optional: file, function, etc.
80
+ };
81
+
82
+ template <typename T>
83
+ using Result = std::expected<T, Error>;
84
+ ```
85
+
86
+ ### Basic Usage
87
+
88
+ ```cpp
89
+ Result<User> find_user(int user_id) {
90
+ auto row = db_.query_one("SELECT * FROM users WHERE id = ?", user_id);
91
+ if (!row) {
92
+ return std::unexpected(Error{
93
+ .code = ErrorCode::kNotFound,
94
+ .message = fmt::format("User {} not found", user_id),
95
+ });
96
+ }
97
+ return User::from_row(*row);
98
+ }
99
+
100
+ // Caller
101
+ auto result = find_user(42);
102
+ if (result) {
103
+ spdlog::info("Found user: {}", result->name());
104
+ } else {
105
+ spdlog::warn("Error: {}", result.error().message);
106
+ }
107
+ ```
108
+
109
+ ### Monadic Chaining (C++23)
110
+
111
+ ```cpp
112
+ // Chain operations that may fail: and_then, transform, or_else
113
+ auto user = find_user(user_id)
114
+ .and_then([](User u) -> Result<User> {
115
+ if (!u.is_active()) {
116
+ return std::unexpected(Error{ErrorCode::kUnauthorized, "User inactive"});
117
+ }
118
+ return u;
119
+ })
120
+ .transform([](User u) {
121
+ return UserResponse{u.name(), u.email()};
122
+ });
123
+ ```
124
+
125
+ ### Pre-C++23 Alternative: tl::expected
126
+
127
+ ```cpp
128
+ // Use tl::expected if your compiler does not yet support std::expected
129
+ #include <tl/expected.hpp>
130
+
131
+ template <typename T>
132
+ using Result = tl::expected<T, Error>;
133
+ ```
134
+
135
+ ---
136
+
137
+ ## When to Use Each Error Strategy
138
+
139
+ | Strategy | Use Case | Example |
140
+ |---|---|---|
141
+ | **std::expected** | Recoverable, expected failures | File not found, validation, business logic |
142
+ | **Exceptions** | Unrecoverable or truly exceptional errors | Out of memory, corrupted state, programmer error |
143
+ | **Error codes (enum)** | C interop, embedded, real-time, no-exception builds | OS APIs, hardware drivers |
144
+ | **std::optional** | "No value" without error details | Cache miss, optional config lookup |
145
+ | **assert / contracts** | Precondition violations in debug builds | `assert(ptr != nullptr)` |
146
+
147
+ ### Exceptions: When Appropriate (CG: E.2, E.3)
148
+
149
+ ```cpp
150
+ // GOOD: Exception for constructor failure (no return value to use)
151
+ class DatabaseConnection {
152
+ public:
153
+ explicit DatabaseConnection(std::string_view conn_str) {
154
+ handle_ = connect(conn_str);
155
+ if (!handle_) {
156
+ throw std::runtime_error(
157
+ fmt::format("Failed to connect to database: {}", conn_str));
158
+ }
159
+ }
160
+ private:
161
+ ConnectionHandle handle_;
162
+ };
163
+
164
+ // GOOD: Exception for programming errors (should not happen in correct code)
165
+ void process(std::span<const int> data) {
166
+ if (data.empty()) {
167
+ throw std::invalid_argument("data must not be empty");
168
+ }
169
+ }
170
+ ```
171
+
172
+ ---
173
+
174
+ ## RAII for Cleanup (CG: R.1)
175
+
176
+ ```cpp
177
+ // GOOD: RAII handles all cleanup automatically
178
+ void transfer_funds(Account& from, Account& to, int amount) {
179
+ auto transaction = db_.begin_transaction(); // RAII: auto-rollback on exception
180
+
181
+ from.withdraw(amount);
182
+ to.deposit(amount);
183
+
184
+ transaction.commit(); // Explicit commit; destructor rolls back if not called
185
+ }
186
+
187
+ // BAD: Manual cleanup -- exception-unsafe
188
+ void transfer_funds_bad(Account& from, Account& to, int amount) {
189
+ auto* txn = db_.begin_transaction_raw();
190
+ from.withdraw(amount); // If this throws, txn is leaked
191
+ to.deposit(amount);
192
+ txn->commit();
193
+ delete txn; // Never reached on exception
194
+ }
195
+ ```
196
+
197
+ ---
198
+
199
+ ## noexcept Specification (CG: E.12)
200
+
201
+ ```cpp
202
+ // GOOD: Mark functions noexcept when they genuinely cannot throw
203
+ void swap(Buffer& other) noexcept;
204
+ Buffer(Buffer&& other) noexcept;
205
+ ~Buffer() noexcept; // Destructors are implicitly noexcept
206
+
207
+ // GOOD: Conditional noexcept for templates
208
+ template <typename T>
209
+ void swap(T& a, T& b) noexcept(std::is_nothrow_move_constructible_v<T>);
210
+
211
+ // BAD: Marking functions noexcept when they might throw
212
+ // If they do throw, std::terminate is called immediately -- no cleanup!
213
+ void parse_config(std::string_view json) noexcept; // JSON parsing can fail!
214
+ ```
215
+
216
+ ---
217
+
218
+ ## Custom Exception Hierarchy (When Using Exceptions)
219
+
220
+ ```cpp
221
+ // Base application exception
222
+ class AppError : public std::runtime_error {
223
+ public:
224
+ explicit AppError(ErrorCode code, std::string_view message)
225
+ : std::runtime_error(std::string(message))
226
+ , code_(code) {}
227
+
228
+ [[nodiscard]] ErrorCode code() const noexcept { return code_; }
229
+
230
+ private:
231
+ ErrorCode code_;
232
+ };
233
+
234
+ class NotFoundError : public AppError {
235
+ public:
236
+ NotFoundError(std::string_view resource, std::string_view id)
237
+ : AppError(ErrorCode::kNotFound,
238
+ fmt::format("{} not found: {}", resource, id)) {}
239
+ };
240
+
241
+ class ValidationError : public AppError {
242
+ public:
243
+ explicit ValidationError(std::string_view message)
244
+ : AppError(ErrorCode::kValidation, message) {}
245
+ };
246
+ ```
247
+
248
+ ---
249
+
250
+ ## Anti-Patterns
251
+
252
+ | Anti-Pattern | Problem | Correct Approach |
253
+ |---|---|---|
254
+ | `catch (...)` with no rethrow | Silently swallows all errors including memory corruption | Catch specific types; rethrow unknown |
255
+ | Catching by value | Slices derived exceptions, copies unnecessarily | Catch by `const` reference: `catch (const Error& e)` |
256
+ | Bare `throw;` in wrong context | UB if no active exception | Only use `throw;` inside a catch block |
257
+ | Ignoring return codes | Missed errors propagate silently | Use `[[nodiscard]]` on error-returning functions |
258
+ | Manual cleanup without RAII | Exception-unsafe, leak-prone | Wrap resources in RAII types |
259
+ | `noexcept` on functions that throw | Calls `std::terminate` with no stack unwinding | Only mark truly non-throwing functions |
260
+ | Using error codes where expected fits | Verbose, easy to ignore | Use `std::expected<T, E>` for typed results |
261
+
262
+ ---
263
+
264
+ _Errors are data. Classify them, make them visible in the type system, and let RAII handle cleanup. Never swallow errors silently._