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
|