henry pushed to branch tor-browser-140.0a1-15.0-1 at The Tor Project / Applications / Tor Browser
Commits:
-
1036d63b
by Henry Wilkes at 2025-06-10T13:54:43+01:00
-
f8d973ab
by Henry Wilkes at 2025-06-10T13:54:45+01:00
4 changed files:
- toolkit/components/tor-launcher/TorBootstrapRequest.sys.mjs
- toolkit/components/tor-launcher/TorProvider.sys.mjs
- toolkit/components/tor-launcher/TorProviderBuilder.sys.mjs
- toolkit/modules/TorConnect.sys.mjs
Changes:
... | ... | @@ -54,9 +54,7 @@ export class TorBootstrapRequest { |
54 | 54 | }
|
55 | 55 | case lazy.TorProviderTopics.BootstrapError: {
|
56 | 56 | log.info("TorBootstrapRequest: observerd TorBootstrapError", obj);
|
57 | - const error = new Error(obj.summary);
|
|
58 | - Object.assign(error, obj);
|
|
59 | - this.#stop(error);
|
|
57 | + this.#stop(obj);
|
|
60 | 58 | break;
|
61 | 59 | }
|
62 | 60 | }
|
... | ... | @@ -6,7 +6,10 @@ import { clearTimeout, setTimeout } from "resource://gre/modules/Timer.sys.mjs"; |
6 | 6 | |
7 | 7 | import { TorLauncherUtil } from "resource://gre/modules/TorLauncherUtil.sys.mjs";
|
8 | 8 | import { TorParsers } from "resource://gre/modules/TorParsers.sys.mjs";
|
9 | -import { TorProviderTopics } from "resource://gre/modules/TorProviderBuilder.sys.mjs";
|
|
9 | +import {
|
|
10 | + TorBootstrapError,
|
|
11 | + TorProviderTopics,
|
|
12 | +} from "resource://gre/modules/TorProviderBuilder.sys.mjs";
|
|
10 | 13 | |
11 | 14 | const lazy = {};
|
12 | 15 | ChromeUtils.defineESModuleGetters(lazy, {
|
... | ... | @@ -996,12 +999,11 @@ export class TorProvider { |
996 | 999 | // anymore, since the first error eligible for notification will as a
|
997 | 1000 | // matter of fact cancel the bootstrap.
|
998 | 1001 | Services.obs.notifyObservers(
|
999 | - {
|
|
1002 | + new TorBootstrapError({
|
|
1000 | 1003 | phase: statusObj.TAG,
|
1001 | 1004 | reason: statusObj.REASON,
|
1002 | 1005 | summary: statusObj.SUMMARY,
|
1003 | - warning: statusObj.WARNING,
|
|
1004 | - },
|
|
1006 | + }),
|
|
1005 | 1007 | TorProviderTopics.BootstrapError
|
1006 | 1008 | );
|
1007 | 1009 | }
|
... | ... | @@ -18,6 +18,41 @@ export const TorProviderTopics = Object.freeze({ |
18 | 18 | CircuitCredentialsMatched: "TorCircuitCredentialsMatched",
|
19 | 19 | });
|
20 | 20 | |
21 | +/**
|
|
22 | + * Wrapper error class for errors raised during TorProvider.init.
|
|
23 | + */
|
|
24 | +export class TorProviderInitError extends Error {
|
|
25 | + /**
|
|
26 | + * Create a new instance.
|
|
27 | + *
|
|
28 | + * @param {any} error - The raised error that we want to wrap.
|
|
29 | + */
|
|
30 | + constructor(error) {
|
|
31 | + super(error?.message, { cause: error });
|
|
32 | + this.name = "TorProviderInitError";
|
|
33 | + }
|
|
34 | +}
|
|
35 | + |
|
36 | +/**
|
|
37 | + * Bootstrap errors raised by the TorProvider.
|
|
38 | + */
|
|
39 | +export class TorBootstrapError extends Error {
|
|
40 | + /**
|
|
41 | + * Create a new instance.
|
|
42 | + *
|
|
43 | + * @param {object} details - Details about the error.
|
|
44 | + * @param {string} details.summary - A summary of the error.
|
|
45 | + * @param {string} details.phase - The bootstrap phase when the error occured.
|
|
46 | + * @param {string} details.reason - The reason for the bootsrap failure.
|
|
47 | + */
|
|
48 | + constructor(details) {
|
|
49 | + super(details.summary);
|
|
50 | + this.name = "TorBootstrapError";
|
|
51 | + this.phase = details.phase;
|
|
52 | + this.reason = details.reason;
|
|
53 | + }
|
|
54 | +}
|
|
55 | + |
|
21 | 56 | export const TorProviders = Object.freeze({
|
22 | 57 | none: 0,
|
23 | 58 | tor: 1,
|
... | ... | @@ -178,7 +213,13 @@ export class TorProviderBuilder { |
178 | 213 | (await oldProvider)?.uninit();
|
179 | 214 | } catch {}
|
180 | 215 | const provider = new lazy.TorProvider();
|
181 | - await provider.init();
|
|
216 | + try {
|
|
217 | + await provider.init();
|
|
218 | + } catch (error) {
|
|
219 | + // Wrap in an error type for callers to know whether the error comes from
|
|
220 | + // initialisation or something else.
|
|
221 | + throw new TorProviderInitError(error);
|
|
222 | + }
|
|
182 | 223 | return provider;
|
183 | 224 | }
|
184 | 225 |
... | ... | @@ -10,6 +10,8 @@ ChromeUtils.defineESModuleGetters(lazy, { |
10 | 10 | MoatRPC: "resource://gre/modules/Moat.sys.mjs",
|
11 | 11 | TorBootstrapRequest: "resource://gre/modules/TorBootstrapRequest.sys.mjs",
|
12 | 12 | TorProviderTopics: "resource://gre/modules/TorProviderBuilder.sys.mjs",
|
13 | + TorBootstrapError: "resource://gre/modules/TorProviderBuilder.sys.mjs",
|
|
14 | + TorProviderInitError: "resource://gre/modules/TorProviderBuilder.sys.mjs",
|
|
13 | 15 | TorLauncherUtil: "resource://gre/modules/TorLauncherUtil.sys.mjs",
|
14 | 16 | TorSettings: "resource://gre/modules/TorSettings.sys.mjs",
|
15 | 17 | TorSettingsTopics: "resource://gre/modules/TorSettings.sys.mjs",
|
... | ... | @@ -223,9 +225,11 @@ class BootstrapAttempt { |
223 | 225 | _timeout: 0,
|
224 | 226 | bootstrap() {
|
225 | 227 | this._timeout = setTimeout(() => {
|
226 | - const err = new Error("Censorship simulation");
|
|
227 | - err.phase = "conn";
|
|
228 | - err.reason = "noroute";
|
|
228 | + const err = new lazy.TorBootstrapError({
|
|
229 | + summary: "Censorship simulation",
|
|
230 | + phase: "conn",
|
|
231 | + reason: "noroute",
|
|
232 | + });
|
|
229 | 233 | this.onbootstraperror(err);
|
230 | 234 | }, options.simulateDelay || 0);
|
231 | 235 | },
|
... | ... | @@ -258,9 +262,7 @@ class BootstrapAttempt { |
258 | 262 | return;
|
259 | 263 | }
|
260 | 264 | |
261 | - this.#resolveRun({
|
|
262 | - error: new TorConnectError(TorConnectError.BootstrapError, error),
|
|
263 | - });
|
|
265 | + this.#resolveRun({ error });
|
|
264 | 266 | };
|
265 | 267 | |
266 | 268 | this.#bootstrap.bootstrap();
|
... | ... | @@ -595,12 +597,9 @@ class AutoBootstrapAttempt { |
595 | 597 | // bootstrapAttempt.
|
596 | 598 | result = await this.#bootstrapAttempt.run(progressCallback, options);
|
597 | 599 | } catch (error) {
|
598 | - // Only re-try with the next settings *if* we have a BootstrapError.
|
|
600 | + // Only re-try with the next settings *if* we have a TorBootstrapError.
|
|
599 | 601 | // Other errors will end this auto-bootstrap attempt entirely.
|
600 | - if (
|
|
601 | - error instanceof TorConnectError &&
|
|
602 | - error.code === TorConnectError.BootstrapError
|
|
603 | - ) {
|
|
602 | + if (error instanceof lazy.TorBootstrapError) {
|
|
604 | 603 | lazy.logger.info("TorConnect setting failed", bridges, error);
|
605 | 604 | // Try with the next settings.
|
606 | 605 | // NOTE: We do not restore the user settings in between these runs.
|
... | ... | @@ -1200,7 +1199,9 @@ export const TorConnect = { |
1200 | 1199 | // Currently it simulates the old behaviour for about:torconnect.
|
1201 | 1200 | lazy.logger.debug("Signalling error", error);
|
1202 | 1201 | |
1203 | - if (!(error instanceof TorConnectError)) {
|
|
1202 | + if (error instanceof lazy.TorBootstrapError) {
|
|
1203 | + error = new TorConnectError(TorConnectError.BootstrapError, error);
|
|
1204 | + } else if (!(error instanceof TorConnectError)) {
|
|
1204 | 1205 | error = new TorConnectError(TorConnectError.ExternalError, error);
|
1205 | 1206 | }
|
1206 | 1207 | this._errorDetails = error;
|
... | ... | @@ -1434,6 +1435,19 @@ export const TorConnect = { |
1434 | 1435 | lazy.logger.info("Bootstrap attempt error", error);
|
1435 | 1436 | this._tryAgain = true;
|
1436 | 1437 | |
1438 | + if (error instanceof lazy.TorProviderInitError) {
|
|
1439 | + // Treat like TorProviderTopics.ProcessExited. We expect a user
|
|
1440 | + // notification when this happens.
|
|
1441 | + // Treat a failure as a possibly broken configuration.
|
|
1442 | + // So, prevent quickstart at the next start.
|
|
1443 | + Services.prefs.setBoolPref(TorConnectPrefs.prompt_at_startup, true);
|
|
1444 | + lazy.logger.info(
|
|
1445 | + "Starting again since the tor provider failed to initialise"
|
|
1446 | + );
|
|
1447 | + this._setStage(TorConnectStage.Start);
|
|
1448 | + return;
|
|
1449 | + }
|
|
1450 | + |
|
1437 | 1451 | if (
|
1438 | 1452 | (beginStage === TorConnectStage.Start ||
|
1439 | 1453 | beginStage === TorConnectStage.Offline) &&
|
... | ... | @@ -1462,10 +1476,7 @@ export const TorConnect = { |
1462 | 1476 | switch (beginStage) {
|
1463 | 1477 | case TorConnectStage.Start:
|
1464 | 1478 | case TorConnectStage.Offline:
|
1465 | - if (
|
|
1466 | - error instanceof TorConnectError &&
|
|
1467 | - error.code === TorConnectError.BootstrapError
|
|
1468 | - ) {
|
|
1479 | + if (error instanceof lazy.TorBootstrapError) {
|
|
1469 | 1480 | errorStage = TorConnectStage.ChooseRegion;
|
1470 | 1481 | }
|
1471 | 1482 | // Else, some other unexpected error type. Skip straight to the
|