nk 1.0.0
C++ Numerical Computing Runtime
Loading...
Searching...
No Matches
error.hpp
1// value/include/nk/value/error.hpp
2//
3// nk::Error — the runtime error type carrying an optional source
4// location (line/col/function/context) and a MATLAB-style identifier.
5//
6// An L0 type: it depends only on the C++ standard library, so every layer —
7// value, ops, the toolboxes, and core — can throw and catch it. (It used to
8// live in core/types.hpp; moving it down lets the foundation/toolboxes report
9// errors without pulling in the engine.) types.hpp re-includes this header so
10// existing `nk::Error` users are unaffected.
11
12#pragma once
13
14#include <stdexcept>
15#include <string>
16
17namespace nk {
18
19// ============================================================
20// Runtime error with source location
21// ============================================================
22class Error : public std::runtime_error
23{
24public:
25 Error(const std::string &msg,
26 int line = 0,
27 int col = 0,
28 const std::string &funcName = "",
29 const std::string &context = "",
30 const std::string &identifier = "")
31 : std::runtime_error(msg) // what() = raw message (clean, for try/catch)
32 , line_(line)
33 , col_(col)
34 , funcName_(funcName)
35 , context_(context)
36 , identifier_(identifier)
37 {}
38
39 int line() const { return line_; }
40 int col() const { return col_; }
41 const std::string &funcName() const { return funcName_; }
42 const std::string &context() const { return context_; }
43 const std::string &identifier() const { return identifier_; }
44
45 // Fill in source-location fields only if they are currently empty.
46 // Called by outer catch blocks (TreeWalker::execNode, VM::dispatchLoop)
47 // to enrich errors thrown deeper in the call stack (e.g. from public
48 // C++ library APIs that don't know their source line) without
49 // overwriting more-precise location already attached by the thrower.
50 void attachIfMissing(int line,
51 int col,
52 const std::string &funcName = "",
53 const std::string &context = "")
54 {
55 if (line_ == 0)
56 line_ = line;
57 if (col_ == 0)
58 col_ = col;
59 if (funcName_.empty() && !funcName.empty())
60 funcName_ = funcName;
61 if (context_.empty() && !context.empty())
62 context_ = context;
63 }
64
65 // Formatted for user display: "Error at line 15, column 3:\n msg (in call to 'sin')"
66 std::string formattedWhat() const
67 {
68 if (line_ <= 0)
69 return what();
70 std::string result = "Error at line " + std::to_string(line_);
71 if (col_ > 0)
72 result += ", column " + std::to_string(col_);
73 if (!funcName_.empty())
74 result += " in '" + funcName_ + "'";
75 result += ":\n ";
76 result += what();
77 if (!context_.empty())
78 result += " (" + context_ + ")";
79 return result;
80 }
81
82private:
83 int line_;
84 int col_;
85 std::string funcName_;
86 std::string context_; // e.g. "in call to 'sin'"
87 std::string identifier_; // e.g. "nk:badInput"
88};
89
90} // namespace nk