This commit is contained in:
chk
2026-06-14 13:41:02 +02:00
parent 8a669f23d3
commit 83cef32a37
5 changed files with 127 additions and 5 deletions

View File

@@ -10734,3 +10734,78 @@
2026-06-14T09:43:07.066Z ::ffff:127.0.0.1: M114 2026-06-14T09:43:07.066Z ::ffff:127.0.0.1: M114
2026-06-14T09:43:07.080Z ::ffff:127.0.0.1: G1 X1 Y2 Z3 2026-06-14T09:43:07.080Z ::ffff:127.0.0.1: G1 X1 Y2 Z3
2026-06-14T09:43:07.211Z ::ffff:127.0.0.1: G1 X1 2026-06-14T09:43:07.211Z ::ffff:127.0.0.1: G1 X1
2026-06-14T11:16:51.101Z ::ffff:127.0.0.1: FList
2026-06-14T11:16:51.136Z ::ffff:127.0.0.1: FPlus
2026-06-14T11:16:51.150Z ::ffff:127.0.0.1: FLoad nichtda
2026-06-14T11:16:51.370Z ::ffff:127.0.0.1: M114
2026-06-14T11:16:51.381Z ::ffff:127.0.0.1: G1 X1 Y2 Z3
2026-06-14T11:16:51.580Z ::ffff:127.0.0.1: M114
2026-06-14T11:16:51.803Z ::ffff:127.0.0.1: G1 X1 Y2 Z3
2026-06-14T11:16:52.031Z ::ffff:127.0.0.1: G1 X1
2026-06-14T11:17:04.735Z ::ffff:127.0.0.1: FList
2026-06-14T11:17:04.743Z ::ffff:127.0.0.1: M114
2026-06-14T11:17:04.750Z ::ffff:127.0.0.1: G1 X1 Y2 Z3
2026-06-14T11:17:04.755Z ::ffff:127.0.0.1: FPlus
2026-06-14T11:17:04.766Z ::ffff:127.0.0.1: FLoad nichtda
2026-06-14T11:17:04.961Z ::ffff:127.0.0.1: M114
2026-06-14T11:17:05.183Z ::ffff:127.0.0.1: G1 X1 Y2 Z3
2026-06-14T11:17:05.412Z ::ffff:127.0.0.1: G1 X1
2026-06-14T11:36:44.546Z ::ffff:127.0.0.1: FList
2026-06-14T11:36:44.568Z ::ffff:127.0.0.1: FPlus
2026-06-14T11:36:44.584Z ::ffff:127.0.0.1: FLoad nichtda
2026-06-14T11:36:44.658Z ::ffff:127.0.0.1: M114
2026-06-14T11:36:44.670Z ::ffff:127.0.0.1: M114
2026-06-14T11:36:44.672Z ::ffff:127.0.0.1: G1 X1 Y2 Z3
2026-06-14T11:36:44.894Z ::ffff:127.0.0.1: G1 X1 Y2 Z3
2026-06-14T11:36:45.172Z ::ffff:127.0.0.1: G1 X1
2026-06-14T11:36:46.643Z ::ffff:127.0.0.1: FList
2026-06-14T11:36:46.672Z ::ffff:127.0.0.1: FPlus
2026-06-14T11:36:46.680Z ::ffff:127.0.0.1: M114
2026-06-14T11:36:46.682Z ::ffff:127.0.0.1: FLoad nichtda
2026-06-14T11:36:46.687Z ::ffff:127.0.0.1: G1 X1 Y2 Z3
2026-06-14T11:36:46.881Z ::ffff:127.0.0.1: M114
2026-06-14T11:36:47.097Z ::ffff:127.0.0.1: G1 X1 Y2 Z3
2026-06-14T11:36:47.331Z ::ffff:127.0.0.1: G1 X1
2026-06-14T11:36:55.467Z ::ffff:127.0.0.1: FList
2026-06-14T11:36:55.476Z ::ffff:127.0.0.1: FPlus
2026-06-14T11:36:55.483Z ::ffff:127.0.0.1: FLoad nichtda
2026-06-14T11:37:15.676Z ::ffff:127.0.0.1: M114
2026-06-14T11:37:15.689Z ::ffff:127.0.0.1: G1 X1 Y2 Z3
2026-06-14T11:37:15.844Z ::ffff:127.0.0.1: FList
2026-06-14T11:37:15.864Z ::ffff:127.0.0.1: FPlus
2026-06-14T11:37:15.871Z ::ffff:127.0.0.1: FLoad nichtda
2026-06-14T11:37:15.878Z ::ffff:127.0.0.1: FShow
2026-06-14T11:37:15.896Z ::ffff:127.0.0.1: M114
2026-06-14T11:37:16.117Z ::ffff:127.0.0.1: G1 X1 Y2 Z3
2026-06-14T11:37:16.348Z ::ffff:127.0.0.1: G1 X1
2026-06-14T11:37:28.740Z ::ffff:127.0.0.1: FList
2026-06-14T11:37:28.764Z ::ffff:127.0.0.1: FPlus
2026-06-14T11:37:28.776Z ::ffff:127.0.0.1: FLoad nichtda
2026-06-14T11:37:28.778Z ::ffff:127.0.0.1: M114
2026-06-14T11:37:28.786Z ::ffff:127.0.0.1: G1 X1 Y2 Z3
2026-06-14T11:37:28.788Z ::ffff:127.0.0.1: FShow
2026-06-14T11:37:29.015Z ::ffff:127.0.0.1: M114
2026-06-14T11:37:29.234Z ::ffff:127.0.0.1: G1 X1 Y2 Z3
2026-06-14T11:37:29.461Z ::ffff:127.0.0.1: G1 X1
2026-06-14T11:37:38.711Z ::ffff:127.0.0.1: FList
2026-06-14T11:37:38.725Z ::ffff:127.0.0.1: FPlus
2026-06-14T11:37:38.735Z ::ffff:127.0.0.1: FLoad nichtda
2026-06-14T11:37:38.742Z ::ffff:127.0.0.1: FShow
2026-06-14T11:37:48.038Z ::ffff:127.0.0.1: M114
2026-06-14T11:37:48.045Z ::ffff:127.0.0.1: FList
2026-06-14T11:37:48.097Z ::ffff:127.0.0.1: G1 X1 Y2 Z3
2026-06-14T11:37:48.111Z ::ffff:127.0.0.1: FPlus
2026-06-14T11:37:48.151Z ::ffff:127.0.0.1: FLoad nichtda
2026-06-14T11:37:48.196Z ::ffff:127.0.0.1: FShow
2026-06-14T11:37:48.807Z ::ffff:127.0.0.1: M114
2026-06-14T11:37:49.023Z ::ffff:127.0.0.1: G1 X1 Y2 Z3
2026-06-14T11:37:49.265Z ::ffff:127.0.0.1: G1 X1
2026-06-14T11:37:51.799Z ::ffff:127.0.0.1: FList
2026-06-14T11:37:51.812Z ::ffff:127.0.0.1: M114
2026-06-14T11:37:51.828Z ::ffff:127.0.0.1: G1 X1 Y2 Z3
2026-06-14T11:37:51.836Z ::ffff:127.0.0.1: FPlus
2026-06-14T11:37:51.855Z ::ffff:127.0.0.1: FLoad nichtda
2026-06-14T11:37:51.866Z ::ffff:127.0.0.1: FShow
2026-06-14T11:37:52.055Z ::ffff:127.0.0.1: M114
2026-06-14T11:37:52.277Z ::ffff:127.0.0.1: G1 X1 Y2 Z3
2026-06-14T11:37:52.509Z ::ffff:127.0.0.1: G1 X1

View File

@@ -14746,3 +14746,19 @@
2026-06-14T09:43:02.856Z ::ffff:127.0.0.1 : Ping 2026-06-14T09:43:02.856Z ::ffff:127.0.0.1 : Ping
2026-06-14T09:43:06.488Z ::ffff:127.0.0.1 : Ping 2026-06-14T09:43:06.488Z ::ffff:127.0.0.1 : Ping
2026-06-14T09:43:07.035Z ::ffff:127.0.0.1 : Ping 2026-06-14T09:43:07.035Z ::ffff:127.0.0.1 : Ping
2026-06-14T11:16:51.344Z ::ffff:127.0.0.1 : Ping
2026-06-14T11:16:51.346Z ::ffff:127.0.0.1 : Ping
2026-06-14T11:17:04.719Z ::ffff:127.0.0.1 : Ping
2026-06-14T11:17:04.733Z ::ffff:127.0.0.1 : Ping
2026-06-14T11:36:44.450Z ::ffff:127.0.0.1 : Ping
2026-06-14T11:36:44.640Z ::ffff:127.0.0.1 : Ping
2026-06-14T11:36:46.636Z ::ffff:127.0.0.1 : Ping
2026-06-14T11:36:46.659Z ::ffff:127.0.0.1 : Ping
2026-06-14T11:37:15.647Z ::ffff:127.0.0.1 : Ping
2026-06-14T11:37:15.667Z ::ffff:127.0.0.1 : Ping
2026-06-14T11:37:28.754Z ::ffff:127.0.0.1 : Ping
2026-06-14T11:37:28.792Z ::ffff:127.0.0.1 : Ping
2026-06-14T11:37:47.975Z ::ffff:127.0.0.1 : Ping
2026-06-14T11:37:48.506Z ::ffff:127.0.0.1 : Ping
2026-06-14T11:37:51.780Z ::ffff:127.0.0.1 : Ping
2026-06-14T11:37:51.825Z ::ffff:127.0.0.1 : Ping

View File

@@ -79,15 +79,31 @@ async function _req(method, path, body) {
opts.headers = { 'content-type': 'application/json' }; opts.headers = { 'content-type': 'application/json' };
opts.body = JSON.stringify(body); opts.body = JSON.stringify(body);
} }
const res = await fetch(url, opts); console.log(`[FCode] → ${method} ${url}${body ? ' ' + JSON.stringify(body) : ''}`);
let res;
try {
res = await fetch(url, opts);
} catch (netErr) {
// Fileservice nicht erreichbar (DNS/Connection refused): klare Meldung statt "fetch failed".
console.error(`[FCode] ✖ ${method} ${url}: Fileservice nicht erreichbar (${netErr.message})`);
const e = new Error(`Fileservice nicht erreichbar: ${netErr.message}`);
e.code = 'FILESERVICE_UNREACHABLE';
throw e;
}
if (!res.ok) { if (!res.ok) {
const err = await res.json().catch(() => ({})); const err = await res.json().catch(() => ({}));
console.error(`[FCode] ✖ ${res.status} ${method} ${path}: ${err.code || ''} ${err.message || res.statusText}`);
const e = new Error(err.message || res.statusText); const e = new Error(err.message || res.statusText);
e.code = err.code; e.code = err.code;
e.status = res.status; e.status = res.status;
throw e; throw e;
} }
return res.json();
const data = await res.json();
console.log(`[FCode] ← ${res.status} ${method} ${path} ${JSON.stringify(data).slice(0, 160)}`);
return data;
} }
module.exports = { isFCode, handle }; module.exports = { isFCode, handle };

View File

@@ -76,10 +76,12 @@ function initInputWS(server, robot, GCode, sharedState) {
* Stepping-Befehle (FPlus/FMinus/…) liefern eine driver-native GCode-Zeile * Stepping-Befehle (FPlus/FMinus/…) liefern eine driver-native GCode-Zeile
* (Radian) zurück, die der Driver direkt ausführt und dann broadcastet. */ * (Radian) zurück, die der Driver direkt ausführt und dann broadcastet. */
if (FCodeClient.isFCode(message)) { if (FCodeClient.isFCode(message)) {
console.log("📁 FCode → Fileservice: " + message);
logCommand(sharedState, clientIP, message); logCommand(sharedState, clientIP, message);
FCodeClient.handle(robot, message) FCodeClient.handle(robot, message)
.then(result => { .then(result => {
if (result.type === 'step' && result.line) { if (result.type === 'step' && result.line) {
console.log("📁 FCode Step → execute: " + result.line);
try { GCode.receiveGCode(robot, result.line); } catch (err) { try { GCode.receiveGCode(robot, result.line); } catch (err) {
return sendError(ws, 'GCODE_ERROR', err.message, result.line); return sendError(ws, 'GCODE_ERROR', err.message, result.line);
} }
@@ -88,7 +90,10 @@ function initInputWS(server, robot, GCode, sharedState) {
broadcast(wss, result.data); broadcast(wss, result.data);
} }
}) })
.catch(err => sendError(ws, 'FILE_ERROR', err.message, message)); .catch(err => {
console.error("📁 FCode FEHLER (" + message + "): " + err.message);
sendError(ws, err.code || 'FILE_ERROR', err.message, message);
});
return; return;
} }

View File

@@ -81,7 +81,7 @@ describe('InputWS FCode-Routing', () => {
expect(robot.sendCommand).toHaveBeenCalled(); expect(robot.sendCommand).toHaveBeenCalled();
}); });
test('Fileservice-Fehler → machine-readable FILE_ERROR an Sender', async () => { test('Fileservice-Fehler → spezifischer Fehlercode wird an Sender durchgereicht', async () => {
const err = Object.assign(new Error('not found'), { code: 'PROGRAM_NOT_FOUND' }); const err = Object.assign(new Error('not found'), { code: 'PROGRAM_NOT_FOUND' });
FCodeClient.handle.mockRejectedValue(err); FCodeClient.handle.mockRejectedValue(err);
await setup(); await setup();
@@ -89,7 +89,17 @@ describe('InputWS FCode-Routing', () => {
ws.send('FLoad nichtda'); ws.send('FLoad nichtda');
const msg = JSON.parse(await replyP); const msg = JSON.parse(await replyP);
expect(msg.type).toBe('error'); expect(msg.type).toBe('error');
expect(msg.code).toBe('FILE_ERROR'); expect(msg.code).toBe('PROGRAM_NOT_FOUND'); // err.code wird durchgereicht (nicht pauschal FILE_ERROR)
expect(msg.input).toBe('FLoad nichtda'); expect(msg.input).toBe('FLoad nichtda');
}); });
test('Fehler ohne code → Fallback FILE_ERROR', async () => {
FCodeClient.handle.mockRejectedValue(new Error('kaputt'));
await setup();
const replyP = nextMessage(ws);
ws.send('FShow');
const msg = JSON.parse(await replyP);
expect(msg.type).toBe('error');
expect(msg.code).toBe('FILE_ERROR');
});
}); });