fix(components): robust version installation and updates across Docker, APK v3 and OPKG
- fix(updater): support single release JSON object for specific tag queries and unblock prereleases on explicit selection - fix(action): replace wget --header with -U for uclient-fetch compatibility on OpenWrt 23.05 - fix(action): make package list updates best-effort to prevent failures on snapshot kmod feeds - fix(action): add offline/corrupt extract fallbacks (apk extract and opkg data.tar.gz) for kernel dependency mismatch - fix(action): ensure /var/lock and /tmp/run directories exist before opkg/procd operations - fix(action): fix fallback asset URL pattern for remittor zapret releases - fix(packages): add binary presence and --version detection fallbacks for zapret, zapret2, byedpi, sing-box - fix(byedpi): support direct apk list parsing for installed package version - fix(state): include schedule, profile, and guest_mode in reload state signatures - fix(imports): fix missing command_status_from_args, write_json, and remove_file imports - fix(updates): extract meaningful ucode errors and strip trailing caret lines
This commit is contained in:
@@ -230,17 +230,65 @@ function text_first_chars(value, max_chars) {
|
||||
|
||||
function file_last_nonblank_line_value(path, fallback, max_chars) {
|
||||
let data = fs.readfile(path);
|
||||
let result = "";
|
||||
if (data == null || trim(as_string(data)) == "")
|
||||
return text_first_chars(fallback, max_chars);
|
||||
|
||||
if (data != null) {
|
||||
for (let line in split(as_string(data), "\n"))
|
||||
if (match(line, /^[[:space:]]*$/) == null)
|
||||
result = line;
|
||||
let raw_lines = split(as_string(data), /\r?\n/);
|
||||
let lines = [];
|
||||
for (let l in raw_lines) {
|
||||
let t = trim(l);
|
||||
if (t != "")
|
||||
push(lines, t);
|
||||
}
|
||||
|
||||
if (result == "")
|
||||
result = as_string(fallback);
|
||||
if (length(lines) == 0)
|
||||
return text_first_chars(fallback, max_chars);
|
||||
|
||||
// 1. Detect ucode runtime/syntax exception
|
||||
let first_line = lines[0];
|
||||
let lower_first = lc(first_line);
|
||||
if (index(lower_first, "type error:") == 0 ||
|
||||
index(lower_first, "syntax error:") == 0 ||
|
||||
index(lower_first, "reference error:") == 0 ||
|
||||
index(lower_first, "runtime error:") == 0 ||
|
||||
index(lower_first, "unhandled exception:") == 0 ||
|
||||
index(lower_first, "error:") == 0) {
|
||||
let loc = "";
|
||||
if (length(lines) > 1 && (index(lines[1], "In ") == 0 || index(lines[1], "in ") == 0)) {
|
||||
let m = match(lines[1], /([a-zA-Z0-9_.-]+),[ \t]*line[ \t]*([0-9]+)/);
|
||||
if (m)
|
||||
loc = " (" + m[1] + ":" + m[2] + ")";
|
||||
}
|
||||
let msg = first_line + loc;
|
||||
return text_first_chars(msg, max_chars);
|
||||
}
|
||||
|
||||
// 2. Discard trailing pointer / caret / delimiter lines
|
||||
while (length(lines) > 0) {
|
||||
let last = lines[length(lines) - 1];
|
||||
if (index(last, "Near here") >= 0 || match(last, /^[ \t\-_^]*$/) || match(last, /^[-=~_]{4,}$/)) {
|
||||
pop(lines);
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (length(lines) == 0)
|
||||
return text_first_chars(fallback, max_chars);
|
||||
|
||||
// 3. Check if any line has an explicit error prefix
|
||||
for (let l in lines) {
|
||||
let lower_l = lc(l);
|
||||
if (index(lower_l, "error:") >= 0 ||
|
||||
index(lower_l, "fatal:") >= 0 ||
|
||||
index(lower_l, "failed:") >= 0 ||
|
||||
index(lower_l, "failure:") >= 0) {
|
||||
return text_first_chars(l, max_chars);
|
||||
}
|
||||
}
|
||||
|
||||
// 4. Fallback to the last non-empty line
|
||||
let result = lines[length(lines) - 1];
|
||||
return text_first_chars(result, max_chars);
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user