Skip to content

Commit 8d0b972

Browse files
committed
feat(cli): add compiler error handler and improve run UX
1 parent 5590f84 commit 8d0b972

5 files changed

Lines changed: 768 additions & 13 deletions

File tree

include/vix/cli/ErrorHandler.hpp

Lines changed: 115 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,115 @@
1+
#pragma once
2+
3+
#include <string>
4+
#include <vector>
5+
#include <filesystem>
6+
7+
namespace vix::cli
8+
{
9+
namespace fs = std::filesystem;
10+
11+
/// Represents a single compiler error extracted from the build log.
12+
struct CompilerError
13+
{
14+
/// Full path to the source file reported by the compiler.
15+
std::string file;
16+
17+
/// 1-based line number in the source file.
18+
int line = 0;
19+
20+
/// 1-based column number in the source file.
21+
int column = 0;
22+
23+
/// Human-readable error message (without the file:line:column prefix).
24+
std::string message;
25+
26+
/// Raw line as seen in the compiler output (for debugging/fallbacks).
27+
std::string raw;
28+
};
29+
30+
/// High-level error reporting helper for the Vix CLI.
31+
///
32+
/// The ErrorHandler is responsible for:
33+
/// - Parsing raw compiler / linker logs (Clang/GCC-style).
34+
/// - Detecting "known" patterns and replacing them with very friendly,
35+
/// colored explanations (especially in script mode: `vix run main.cpp`).
36+
/// - Falling back to a compact list of errors when no special pattern matches.
37+
class ErrorHandler
38+
{
39+
public:
40+
/// Parse a build log and print a friendly summary to stderr.
41+
///
42+
/// This method:
43+
/// - Extracts structured compiler errors (file, line, column, message).
44+
/// - Handles special cases (common C++ mistakes) with educational messages.
45+
/// - Optionally detects linker and sanitizer errors from the raw log.
46+
///
47+
/// \param buildLog
48+
/// Full textual output captured from the build command
49+
/// (stdout + stderr).
50+
///
51+
/// \param sourceFile
52+
/// The main source file for the script or target being built.
53+
/// Used only for display (e.g., `Source file: main.cpp`).
54+
///
55+
/// \param contextMessage
56+
/// Short label describing the context (defaults to "Script build failed").
57+
/// This is used in generic error headers when no special case applies.
58+
static void printBuildErrors(
59+
const std::string &buildLog,
60+
const fs::path &sourceFile,
61+
const std::string &contextMessage = "Script build failed");
62+
63+
private:
64+
/// Parse Clang/GCC-style errors from the build log.
65+
///
66+
/// Expected format (simplified):
67+
/// /path/to/file.cpp:line:column: error: message...
68+
/// /path/to/file.hpp:line:column: fatal error: message...
69+
///
70+
/// Only "error" and "fatal error" entries are returned (warnings are ignored).
71+
static std::vector<CompilerError> parseClangGccErrors(
72+
const std::string &buildLog);
73+
74+
/// Print a single compiler error in a compact, human-friendly format.
75+
///
76+
/// Typically used for generic build output (non–special-case handling),
77+
/// for example:
78+
///
79+
/// main.cpp:17:5
80+
/// error: use of undeclared identifier 'foo'
81+
static void printSingleError(const CompilerError &err);
82+
83+
/// Print small, generic hints for common error messages.
84+
///
85+
/// Examples:
86+
/// - Missing `std` namespace.
87+
/// - Missing semicolon.
88+
/// - No matching function for a given call.
89+
static void printHints(const CompilerError &err);
90+
91+
/// Handle "known" error patterns with very friendly, high-level messages.
92+
///
93+
/// This is where we turn cryptic compiler diagnostics into something like:
94+
///
95+
/// ❌ ERROR: Cannot print std::vector<int> using operator<<
96+
///
97+
/// 💡 Tip:
98+
/// std::cout << value; // ❌ invalid
99+
/// for (auto x : value) // ✔ correct
100+
/// std::cout << x << std::endl;
101+
///
102+
/// 📍 Source: main.cpp:18
103+
///
104+
/// If a pattern is recognized and a custom message is printed, this
105+
/// function returns true and the generic error printing pipeline is skipped.
106+
///
107+
/// \return true if the error set has already been handled and printed
108+
/// with a custom message; false otherwise.
109+
static bool handleSpecialCases(
110+
const std::vector<CompilerError> &errors,
111+
const fs::path &sourceFile,
112+
const std::string &contextMessage);
113+
};
114+
115+
} // namespace vix::cli

include/vix/cli/commands/run/RunDetail.hpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
#include <string>
66
#include <string_view>
77
#include <vector>
8+
#include "vix/cli/ErrorHandler.hpp"
89

910
namespace vix::commands::RunCommand::detail
1011
{

0 commit comments

Comments
 (0)