Skip to content

Commit 5b66458

Browse files
authored
Merge pull request #176 from DiyunZ/Error_Message
Error message
2 parents c315276 + c881b19 commit 5b66458

22 files changed

Lines changed: 1537 additions & 672 deletions

‎CMOD/ERROR_REPORTING.md‎

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
# CMOD error reporting
2+
3+
CMOD writes diagnostics to standard error. LASSIE's Process Output window
4+
already displays that stream and marks failed processes in red.
5+
6+
| Exit code | Meaning |
7+
| --- | --- |
8+
| 0 | The requested build completed. |
9+
| 1 | A diagnosed project-input or output failure. |
10+
| 2 | An unexpected C++ exception or a diagnosed internal error. |
11+
12+
For example, a missing configuration field produces:
13+
14+
```text
15+
CMOD project error: A required project setting is missing.
16+
Project: Example.dissco
17+
Context: ProjectConfiguration.NumberOfChannels
18+
Suggestion: Restore this setting in Project Properties, then save the project in LASSIE.
19+
Build failed.
20+
```
21+
22+
Project diagnostics cover unreadable or malformed project XML, missing or invalid
23+
configuration, invalid numeric expressions and nested functions, missing object
24+
references, invalid Select indices, functions used without an event context,
25+
invalid child counts, and empty score staffs. Output diagnostics cover directory
26+
creation, temporary library files, audio/score writes, and LilyPond failures.
27+
Unexpected C++ exceptions ask the user to send developers the project, seed,
28+
and diagnostic. Hard process faults and remaining legacy direct-exit paths
29+
retain their existing handling; they are not made recoverable by these exceptions.
30+
31+
## Adding a diagnostic
32+
33+
Throw `CmodError` with a category, a specific reason, input context, and a
34+
corrective action. Add outer context while rethrowing at a boundary that knows
35+
the project field or expression. Do not discard an underlying parser's reason,
36+
or classify an arbitrary `std::exception` as a user-input error.
37+
38+
`Main.cpp` reports the exception once and returns a nonzero exit code. A failed
39+
run must not reach its `Build complete.` message.

‎CMOD/src/Bottom.cpp‎

Lines changed: 274 additions & 130 deletions
Large diffs are not rendered by default.

‎CMOD/src/CmodError.h‎

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
#ifndef CMOD_ERROR_H
2+
#define CMOD_ERROR_H
3+
4+
#include <ostream>
5+
#include <stdexcept>
6+
#include <string>
7+
8+
// Expected failures retain the input context and a useful next step while
9+
// unwinding to the command-line boundary. Unexpected exceptions are internal.
10+
class CmodError : public std::runtime_error {
11+
public:
12+
enum class Kind { Project, Output, Internal };
13+
14+
CmodError(Kind kind, const std::string& message,
15+
const std::string& context, const std::string& suggestion)
16+
: std::runtime_error(message), kind_(kind), context_(context),
17+
suggestion_(suggestion) {}
18+
19+
void addContext(const std::string& context) {
20+
context_ = context + (context_.empty() ? "" : " -> " + context_);
21+
}
22+
23+
int exitCode() const { return kind_ == Kind::Internal ? 2 : 1; }
24+
25+
void report(std::ostream& output, const std::string& project) const {
26+
const char* category = kind_ == Kind::Project ? "project"
27+
: kind_ == Kind::Output ? "output" : "internal";
28+
output << "CMOD " << category << " error: " << what() << '\n'
29+
<< "Project: " << project << '\n';
30+
if (!context_.empty())
31+
output << "Context: " << context_ << '\n';
32+
output << "Suggestion: " << suggestion_ << '\n'
33+
<< "Build failed." << std::endl;
34+
}
35+
36+
private:
37+
Kind kind_;
38+
std::string context_;
39+
std::string suggestion_;
40+
};
41+
42+
#endif

0 commit comments

Comments
 (0)