Fix error starting instance on unlisted versions

The FactorioServer.checkForUpdates function would wrongfully assume that
the version running would always be listed on Wube's archive page, and
throw an error if this was not the case.  Ignore version checking logic
if no suitable latest version could be found.
This commit is contained in:
Hornwitser committed 2026-03-09 15:16:26 +01:00
1 parent f56605600f
commit 25d98d2ab3
3 files changed
+124 -256

No files matched your search

+4
View File
@@ -978,6 +978,10 @@ export class FactorioServer extends events.EventEmitter<FactorioServerEvents> {
.sort((v1, v2) => versionOrder(v1.version, v2.version))
[0];
if (!latestVersion) {
return;
}
const installedVersions = await listFactorioVersions(this._factorioDir);
if (!installedVersions.versions.has(latestVersion.version)) {
const v = latestVersion.version;
+114 -256
View File
@@ -342,264 +342,122 @@ describe("host/server", function() {
});
});
describe("full version", function() {
it("should do nothing when there is no newer version", async function() {
server._factorioDir = path.join("test", "file", "factorio");
server._targetVersion = "0.1.1";
await server.checkForUpdates([{
stable: true,
version: "0.1.1",
headlessUrl: "test1",
}, {
stable: false,
version: "0.1.0",
headlessUrl: "test2",
}]);
for (const [suite, target] of [
["full version", "0.1.1"],
["partial version", "0.1"],
["latest version", "latest"],
]) {
/* eslint-disable no-loop-func */
describe("full version", function() {
it("should do nothing when there are no versions", async function() {
server._factorioDir = path.join("test", "file", "factorio");
server._targetVersion = target;
await server.checkForUpdates([]);
assert.equal(fetchCalledWith, null);
assert.equal(fetchCalledWith, null);
});
it("should do nothing when no version matches", async function() {
server._factorioDir = path.join("test", "file", "factorio");
server._targetVersion = target;
await server.checkForUpdates([{
stable: true,
version: "0.2.1",
headlessUrl: "test1",
}, {
stable: false,
version: "0.2.0",
headlessUrl: "test2",
}]);
assert.equal(fetchCalledWith, null);
});
it("should do nothing when there is no newer version", async function() {
server._factorioDir = path.join("test", "file", "factorio");
server._targetVersion = target;
await server.checkForUpdates([{
stable: true,
version: "0.1.1",
headlessUrl: "test1",
}, {
stable: false,
version: "0.1.0",
headlessUrl: "test2",
}]);
assert.equal(fetchCalledWith, null);
});
it("should do nothing for direct installs", async function() {
server._factorioDir = path.join("test", "file", "factorio", "0.1.1");
server._targetVersion = target === "0.1.1" ? "0.1.5" : target;
await server.checkForUpdates([{
stable: true,
version: "0.1.5",
headlessUrl: "test1",
}, {
stable: true,
version: "0.1.1",
headlessUrl: "test1",
}, {
stable: false,
version: "0.1.0",
headlessUrl: "test2",
}]);
assert.equal(fetchCalledWith, null);
});
it("should do nothing when on windows", async function() {
let logLine = null;
server._logger = { info: line => { logLine = line; } };
Object.defineProperty(process, "platform", { value: "win32" });
server._factorioDir = path.join("test", "file", "factorio");
server._targetVersion = target === "0.1.1" ? "0.1.5" : target;
await server.checkForUpdates([{
stable: true,
version: "0.1.5",
headlessUrl: "test1",
}, {
stable: true,
version: "0.1.1",
headlessUrl: "test2",
}, {
stable: false,
version: "0.1.0",
headlessUrl: "test3",
}]);
assert.equal(fetchCalledWith, null);
assert.ok(logLine !== null);
assert.ok(logLine.endsWith("but must be manually downloaded"));
});
it("should do attempt to download on linux", async function() {
let logLine = null;
server._logger = { info: line => { logLine = line; } };
Object.defineProperty(process, "platform", { value: "linux" });
server._factorioDir = path.join("test", "file", "factorio");
server._targetVersion = target === "0.1.1" ? "0.1.5" : target;
await assert.rejects(server.checkForUpdates([{
stable: true,
version: "0.1.5",
headlessUrl: "test1",
}, {
stable: true,
version: "0.1.1",
headlessUrl: "test2",
}, {
stable: false,
version: "0.1.0",
headlessUrl: "test3",
}]), new Error("Failed to fetch test1: -1 Fetch called"));
assert.equal(fetchCalledWith, "test1");
assert.ok(logLine !== null);
assert.ok(logLine.endsWith("starting download..."));
});
});
it("should do nothing for direct installs", async function() {
server._factorioDir = path.join("test", "file", "factorio", "0.1.1");
server._targetVersion = "0.1.5";
await server.checkForUpdates([{
stable: true,
version: "0.1.5",
headlessUrl: "test1",
}, {
stable: true,
version: "0.1.1",
headlessUrl: "test1",
}, {
stable: false,
version: "0.1.0",
headlessUrl: "test2",
}]);
assert.equal(fetchCalledWith, null);
});
it("should do nothing when on windows", async function() {
let logLine = null;
server._logger = { info: line => { logLine = line; } };
Object.defineProperty(process, "platform", { value: "win32" });
server._factorioDir = path.join("test", "file", "factorio");
server._targetVersion = "0.1.5";
await server.checkForUpdates([{
stable: true,
version: "0.1.5",
headlessUrl: "test1",
}, {
stable: true,
version: "0.1.1",
headlessUrl: "test2",
}, {
stable: false,
version: "0.1.0",
headlessUrl: "test3",
}]);
assert.equal(fetchCalledWith, null);
assert.ok(logLine !== null);
assert.ok(logLine.endsWith("but must be manually downloaded"));
});
it("should do attempt to download on linux", async function() {
let logLine = null;
server._logger = { info: line => { logLine = line; } };
Object.defineProperty(process, "platform", { value: "linux" });
server._factorioDir = path.join("test", "file", "factorio");
server._targetVersion = "0.1.5";
await assert.rejects(server.checkForUpdates([{
stable: true,
version: "0.1.5",
headlessUrl: "test1",
}, {
stable: true,
version: "0.1.1",
headlessUrl: "test2",
}, {
stable: false,
version: "0.1.0",
headlessUrl: "test3",
}]), new Error("Failed to fetch test1: -1 Fetch called"));
assert.equal(fetchCalledWith, "test1");
assert.ok(logLine !== null);
assert.ok(logLine.endsWith("starting download..."));
});
});
describe("partial version", function() {
it("should do nothing when there is no newer version", async function() {
server._factorioDir = path.join("test", "file", "factorio");
server._targetVersion = "0.1";
await server.checkForUpdates([{
stable: true,
version: "0.1.1",
headlessUrl: "test1",
}, {
stable: false,
version: "0.1.0",
headlessUrl: "test2",
}]);
assert.equal(fetchCalledWith, null);
});
it("should do nothing for direct installs", async function() {
server._factorioDir = path.join("test", "file", "factorio", "0.1.1");
server._targetVersion = "0.1";
await server.checkForUpdates([{
stable: true,
version: "0.1.5",
headlessUrl: "test1",
}, {
stable: true,
version: "0.1.1",
headlessUrl: "test1",
}, {
stable: false,
version: "0.1.0",
headlessUrl: "test2",
}]);
assert.equal(fetchCalledWith, null);
});
it("should do nothing when on windows", async function() {
let logLine = null;
server._logger = { info: line => { logLine = line; } };
Object.defineProperty(process, "platform", { value: "win32" });
server._factorioDir = path.join("test", "file", "factorio");
server._targetVersion = "0.1";
await server.checkForUpdates([{
stable: true,
version: "0.1.5",
headlessUrl: "test1",
}, {
stable: true,
version: "0.1.1",
headlessUrl: "test2",
}, {
stable: false,
version: "0.1.0",
headlessUrl: "test3",
}]);
assert.equal(fetchCalledWith, null);
assert.ok(logLine !== null);
assert.ok(logLine.endsWith("but must be manually downloaded"));
});
it("should do attempt to download on linux", async function() {
let logLine = null;
server._logger = { info: line => { logLine = line; } };
Object.defineProperty(process, "platform", { value: "linux" });
server._factorioDir = path.join("test", "file", "factorio");
server._targetVersion = "0.1";
await assert.rejects(server.checkForUpdates([{
stable: true,
version: "0.1.5",
headlessUrl: "test1",
}, {
stable: true,
version: "0.1.1",
headlessUrl: "test2",
}, {
stable: false,
version: "0.1.0",
headlessUrl: "test3",
}]), new Error("Failed to fetch test1: -1 Fetch called"));
assert.equal(fetchCalledWith, "test1");
assert.ok(logLine !== null);
assert.ok(logLine.endsWith("starting download..."));
});
});
describe("latest version", function() {
it("should do nothing when there is no newer version", async function() {
server._factorioDir = path.join("test", "file", "factorio");
server._targetVersion = "latest";
await server.checkForUpdates([{
stable: true,
version: "0.1.1",
headlessUrl: "test1",
}, {
stable: false,
version: "0.1.0",
headlessUrl: "test2",
}]);
assert.equal(fetchCalledWith, null);
});
it("should do nothing for direct installs", async function() {
server._factorioDir = path.join("test", "file", "factorio", "0.1.1");
server._targetVersion = "latest";
await server.checkForUpdates([{
stable: true,
version: "0.1.5",
headlessUrl: "test1",
}, {
stable: true,
version: "0.1.1",
headlessUrl: "test1",
}, {
stable: false,
version: "0.1.0",
headlessUrl: "test2",
}]);
assert.equal(fetchCalledWith, null);
});
it("should do nothing when on windows", async function() {
let logLine = null;
server._logger = { info: line => { logLine = line; } };
Object.defineProperty(process, "platform", { value: "win32" });
server._factorioDir = path.join("test", "file", "factorio");
server._targetVersion = "latest";
await server.checkForUpdates([{
stable: true,
version: "0.1.5",
headlessUrl: "test1",
}, {
stable: true,
version: "0.1.1",
headlessUrl: "test2",
}, {
stable: false,
version: "0.1.0",
headlessUrl: "test3",
}]);
assert.equal(fetchCalledWith, null);
assert.ok(logLine !== null);
assert.ok(logLine.endsWith("but must be manually downloaded"));
});
it("should do attempt to download on linux", async function() {
let logLine = null;
server._logger = { info: line => { logLine = line; } };
Object.defineProperty(process, "platform", { value: "linux" });
server._factorioDir = path.join("test", "file", "factorio");
server._targetVersion = "latest";
await assert.rejects(server.checkForUpdates([{
stable: true,
version: "0.1.5",
headlessUrl: "test1",
}, {
stable: true,
version: "0.1.1",
headlessUrl: "test2",
}, {
stable: false,
version: "0.1.0",
headlessUrl: "test3",
}]), new Error("Failed to fetch test1: -1 Fetch called"));
assert.equal(fetchCalledWith, "test1");
assert.ok(logLine !== null);
assert.ok(logLine.endsWith("starting download..."));
});
});
/* eslint-enable no-loop-func */
}
it("should download a version correctly (live api)", async function() {
slowTest(this);
if (_platform !== "linux") {
+6
View File
@@ -121,6 +121,12 @@ describe("FactorioVersions", function() {
assert.equal(versions.filter(v => v.stable).length, 48);
assert.equal(versions.filter(v => !v.stable).length, 57);
});
it("parses versions from empty html file", async function() {
mockFetch("");
const versions = await fetchFactorioVersions();
assert.equal(versions.length, 0);
});
it("parses versions from live api", async function() {
slowTest(this);
global.fetch = originalFetch;