mirror of
https://github.com/Termix-SSH/Termix.git
synced 2026-10-23 20:11:03 +00:00
* feat: AI translations at release, 7 new languages and regional fallback * fix: proper plural forms for count strings and full translations * fix: plural forms for selected, hidden and active counts * fix: synced plugin updates failing on desktop and server-only plugins shown as stopped * fix: restore rounded corners on app icons and favicon * feat: desktop app auto updates with automatic, ask first or never modes * feat: community and custom plugin registries * feat: plugin guide for AI tools in the SDK with a lint check * fix: keep the terminal WebSocket open past nginx's 60s default (#1588) * chore: update changelog * feat: show plugin download counts only and stop CI builds inflating them * feat: hide installed plugins in the browse tab by default * chore: pin bundled plugins to latest releases * chore: update translations * fix: focusing a saved password field and saving no longer erases it * fix: tell desktop users when their 2.8 data needs 2.9 first * fix: point windows update info at the x64 installer * fix: keep desktop client tunnel sockets alive behind proxies * chore: pin bundled plugins to latest releases * fix: cover client tunnel keepalive in the c2s runtime tests * fix: typing after opening a host no longer goes to the host search * fix: accept tab and = separators in SSH config import (#1598) * chore: update changelog * chore: drop plugin versions from core changelog * chore: update translations * chore: lint, format, and bump version to 26.10.1 --------- Co-authored-by: Darnel Hunter <68697450+innotelinc@users.noreply.github.com> Co-authored-by: Iain <Iain1970@protonmail.com>
74 lines
2.4 KiB
TypeScript
74 lines
2.4 KiB
TypeScript
import { createRequire } from "node:module";
|
|
import { describe, expect, it } from "vitest";
|
|
import { PRE_29_DATABASE_ERROR } from "../src/backend/database/db/upgrade-guard.js";
|
|
|
|
const require = createRequire(import.meta.url);
|
|
const { classifyBackendFailure } =
|
|
require("../electron/backend-failure.cjs") as {
|
|
classifyBackendFailure: (stderr: string) => {
|
|
reason: string;
|
|
port: number | null;
|
|
};
|
|
};
|
|
|
|
const EADDRINUSE_STDERR = `[2:50:37 PM] [ERROR] [DB] Port 30001 is already in use. Kill the existing process and retry. [op:http_server_port_conflict]
|
|
Error: listen EADDRINUSE: address already in use :::30001
|
|
at Server.setupListenHandle [as _listen2] (node:net:2009:16) {
|
|
code: 'EADDRINUSE',
|
|
errno: -98,
|
|
syscall: 'listen',
|
|
address: '::',
|
|
port: 30001
|
|
}`;
|
|
|
|
describe("classifyBackendFailure", () => {
|
|
// Only reached for exits stopBackendServer() did not ask for, so every
|
|
// exit is a failure the renderer has to be told about: the process is
|
|
// gone either way, and nothing ever restarts it.
|
|
it("identifies a port conflict and the port it happened on", () => {
|
|
expect(classifyBackendFailure(EADDRINUSE_STDERR)).toEqual({
|
|
reason: "port-in-use",
|
|
port: 30001,
|
|
});
|
|
});
|
|
|
|
it("still reports a port conflict when the buffered stderr lost the numeric port field", () => {
|
|
expect(
|
|
classifyBackendFailure(
|
|
"Error: listen EADDRINUSE: address already in use :::30001",
|
|
),
|
|
).toEqual({ reason: "port-in-use", port: 30001 });
|
|
});
|
|
|
|
it("falls back to a null port when EADDRINUSE carries no parsable port", () => {
|
|
expect(classifyBackendFailure("code: 'EADDRINUSE'")).toEqual({
|
|
reason: "port-in-use",
|
|
port: null,
|
|
});
|
|
});
|
|
|
|
it("identifies a 2.8 database the backend refused to open", () => {
|
|
const stderr = `[ERROR] [SYSTEM] Failed to initialize backend services [op:startup_failed]
|
|
Error: ${PRE_29_DATABASE_ERROR}
|
|
at assertNotPre29Database (upgrade-guard.js:14:11)`;
|
|
expect(classifyBackendFailure(stderr)).toEqual({
|
|
reason: "old-database",
|
|
port: null,
|
|
});
|
|
});
|
|
|
|
it("reports a crash for any other non-zero exit", () => {
|
|
expect(classifyBackendFailure("TypeError: boom")).toEqual({
|
|
reason: "crashed",
|
|
port: null,
|
|
});
|
|
});
|
|
|
|
it("reports a crash for a signal kill, which leaves no stderr at all", () => {
|
|
expect(classifyBackendFailure("")).toEqual({
|
|
reason: "crashed",
|
|
port: null,
|
|
});
|
|
});
|
|
});
|