-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy patherror_handler.cpp
More file actions
106 lines (88 loc) · 2.99 KB
/
error_handler.cpp
File metadata and controls
106 lines (88 loc) · 2.99 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
/*
* TT Control, advanced sinusoidal control of multi-phase turntable motors
* Created by Ashley Cox at The Blind Man’s Workshop
* https://theblindmansworkshop.com
* No part of this code may be used or reproduced for commercial purposes without written permission and contractual agreement
* All external libraries and frameworks are the property of their respective authors and governed by their respective licenses
*/
#include "error_handler.h"
#include "ui.h"
#include "settings.h"
extern UserInterface ui;
ErrorHandler errorHandler;
ErrorHandler::ErrorHandler() {
_criticalError = false;
}
void ErrorHandler::begin() {
// Filesystem initialization is handled by Settings class
}
void ErrorHandler::report(ErrorCode code, const char* message, bool critical) {
if (critical) _criticalError = true;
// 1. Log to Serial Console for debugging
Serial.print("ERROR ");
Serial.print(code);
Serial.print(": ");
Serial.println(message);
// 2. Append to persistent log file
logToFile(code, message);
// 3. Display visual alert on UI
if (settings.get().errorDisplayEnabled) {
// Critical errors stay longer (10s) vs warnings (3s) -> Now Configurable
uint32_t duration = settings.get().errorDisplayDuration * 1000;
if (critical && duration < 10000) duration = 10000; // Force min 10s for critical
ui.showError(message, duration);
}
// Note: If critical, the system should ideally stop the motor.
// This is currently handled by the UI or main loop checking `hasCriticalError()`
// or by the caller of `report()`.
}
void ErrorHandler::logToFile(ErrorCode code, const char* message) {
// Check file size first
File f = LittleFS.open("/error.log", "r");
if (f) {
size_t size = f.size();
f.close();
// Rotate if > 10KB
if (size > 10240) {
LittleFS.remove("/error.bak");
LittleFS.rename("/error.log", "/error.bak");
}
}
f = LittleFS.open("/error.log", "a");
if (f) {
f.print(hal.getMillis());
f.print(",");
f.print(code);
f.print(",");
f.println(message);
f.close();
}
}
void ErrorHandler::clearLogs() {
LittleFS.remove("/error.log");
}
void ErrorHandler::dumpLog(Stream& out) {
File f = LittleFS.open("/error.log", "r");
if (!f) {
out.println("No log file.");
return;
}
while (f.available()) {
out.write(f.read());
}
f.close();
}
void ErrorHandler::getLogLines(std::vector<String>& lines, int maxLines) {
File f = LittleFS.open("/error.log", "r");
if (!f) return;
// Read lines from the beginning of the file
// TODO: For large logs, implementing a tail reader would be more efficient
while (f.available() && (int)lines.size() < maxLines) {
String line = f.readStringUntil('\n');
line.trim();
if (line.length() > 0) {
lines.push_back(line);
}
}
f.close();
}