electron-builder: cannot catch errors like net::ERR_NETWORK_CHANGED, net::ERR_CONNECTION_RESET

  • Version: 19.49.0
  • Target: macOS, Windows

description of what you’re trying to do: I am trying to catch errors like: net::ERR_NETWORK_CHANGED, net::ERR_CONNECTION_RESET, net::ERR_SPDY_PROTOCOL_ERROR, net::ERR_CONNECTION_CLOSED etc, but autoUpdater.on(‘error’, errorHandler); (import { autoUpdater } from ‘electron-updater’;) does not catch them and errors go straight to process.on(‘uncaughtException’, handleUncaught). Most errors occur when the internet connection is lost while downloading an update.

package.json:

{
"name": "electron-react-boilerplate",
"productName": "ElectronReact",
"version": "0.10.0",
"description": "Electron application boilerplate based on React, React Router, Webpack, React Hot Loader for rapid application development",
"main": "main.js",
"scripts": {
"hot-updates-server": "cross-env NODE_ENV=development node --trace-warnings -r babel-register ./node_modules/webpack-dev-server/bin/webpack-dev-server --config webpack.config.renderer.dev.js",
"build": "concurrently \"npm run build-main\" \"npm run build-renderer\"",
"build-dll": "cross-env NODE_ENV=development node --trace-warnings -r babel-register ./node_modules/webpack/bin/webpack --config webpack.config.renderer.dev.dll.js --progress --profile --colors",
"build-main": "cross-env NODE_ENV=production node --trace-warnings -r babel-register ./node_modules/webpack/bin/webpack --config webpack.config.main.prod.js --progress --profile --colors",
"build-renderer": "cross-env NODE_ENV=production node --trace-warnings -r babel-register ./node_modules/webpack/bin/webpack --config webpack.config.renderer.prod.js --progress --profile --colors",
"start": "cross-env NODE_ENV=production electron ./app/",
"start-hot-renderer": "cross-env HOT=1 NODE_ENV=development electron -r babel-register -r babel-polyfill ./app/main.development",
"postinstall": "concurrently \"npm run build-dll\" \"install-app-deps\" \"node node_modules/fbjs-scripts/node/check-dev-engines.js package.json\"",
"dev": "cross-env START_HOT=1 npm run hot-updates-server",
"package": "npm run build && build --publish never",
"package-win-64": "npm run build && build --win --x64",
"package-win-32": "npm run build && build --win --ia32",
"package-linux": "npm run build && build --linux",
"package-all": "npm run build && build -mwl",
"cleanup": "mop -v"
},
"browserslist": "electron 1.8.1",
"build": {
"productName": "FontBase",
"appId": "com.dominiklevitsky.fontbase",
"asar": true,
"dmg": {
"icon": "installer.icns",
"contents": [
{
"x": 410,
"y": 150,
"type": "link",
"path": "/Applications"
},
{
"x": 130,
"y": 150,
"type": "file"
}
]
},
"nsis": {
"installerIcon": "installer.ico",
"uninstallerIcon": "installer.ico",
"artifactName": "${productName}-${version}.${ext}"
},
"files": [
"node_modules/",
"providers/",
"assets/icons/",
"dist/main.js",
"dist/app.js",
"dist/synchronizer.js",
"dist/activator.js",
"dist/filemanager.js",
"dist/style.css",
"auth0.min.js",
"app.html",
"synchronizer.html",
"activator.html",
"filemanager.html",
"error.html",
"package.json"
],
"win": {
"target": "nsis",
"icon": "resources/icon.ico"
},
"linux": {
"target": [
"deb",
"AppImage"
]
},
"publish": {
"provider": "generic",
"url": "https://releases.fontba.se/${os}/"
},
"directories": {
"buildResources": "resources",
"output": "release"
}
},
"devDependencies": {
"asar": "^0.13.0",
"babel-core": "^6.26.0",
"babel-loader": "^7.1.2",
"babel-plugin-add-module-exports": "^0.2.1",
"babel-plugin-dev-expression": "^0.2.1",
"babel-plugin-dynamic-import-webpack": "^1.0.1",
"babel-plugin-root-import": "^5.1.0",
"babel-plugin-transform-class-properties": "^6.24.1",
"babel-plugin-transform-es2015-classes": "^6.24.1",
"babel-polyfill": "^6.26.0",
"babel-preset-env": "^1.6.0",
"babel-preset-react": "^6.24.1",
"babel-preset-react-hmre": "^1.1.1",
"babel-preset-react-optimize": "^1.0.1",
"babel-preset-stage-0": "^6.24.1",
"babel-register": "^6.26.0",
"brfs": "^1.4.3",
"concurrently": "^3.5.0",
"cross-env": "^5.0.5",
"css-loader": "^0.28.7",
"electron": "^1.8.0",
"electron-builder": "^19.27.7",
"electron-builder-squirrel-windows": "^19.27.3",
"electron-debug": "^1.4.0",
"electron-devtools-installer": "^2.2.0",
"electron-rebuild": "^1.6.0",
"express": "^4.15.4",
"extract-text-webpack-plugin": "^3.0.0",
"fbjs-scripts": "^0.8.1",
"file-loader": "^0.11.2",
"html-webpack-plugin": "^2.30.1",
"if-webpack-plugin": "^1.0.3",
"node-sass": "^4.5.3",
"packageify": "^1.0.0",
"redux-logger": "^3.0.6",
"sass-loader": "^6.0.6",
"string-replace-webpack-plugin": "^0.1.3",
"style-loader": "^0.18.2",
"svg-inline-loader": "^0.8.0",
"transform-loader": "^0.2.4",
"uglifyjs-webpack-plugin": "^1.1.1",
"url-loader": "^0.5.9",
"webpack": "^3.5.5",
"webpack-dev-server": "^2.7.1",
"webpack-merge": "^4.1.0"
},
"dependencies": {
"base-64": "^0.1.0",
"classnames": "^2.2.5",
"electron-updater": "^2.16.3",
"electron-window-state": "^4.1.1",
"file-url": "^2.0.2",
"fontkit": "^1.7.7",
"history": "^4.7.2",
"immutable": "^3.8.1",
"jwt-decode": "^2.2.0",
"localforage": "^1.5.0",
"lodash": "^4.17.4",
"mkdirp": "^0.5.1",
"mousetrap": "^1.6.1",
"rc-slider": "^8.3.1",
"react": "^16.2.0",
"react-color": "^2.13.5",
"react-dnd": "^2.5.4",
"react-dnd-html5-backend": "^2.4.1",
"react-dom": "^16.2.0",
"react-hot-loader": "^3.0.0-beta.6",
"react-onclickoutside": "^6.5.0",
"react-redux": "^5.0.6",
"react-resize-detector": "^1.1.0",
"react-router": "^3.0.5",
"react-router-dom": "^4.1.1",
"react-router-redux": "^4.0.8",
"react-timeout": "^1.0.1",
"react-virtualized": "^9.9.0",
"redux": "^3.7.2",
"redux-persist": "^4.9.1",
"redux-persist-immutable": "^4.3.1",
"redux-thunk": "^2.2.0",
"reselect": "^3.0.1",
"source-map-support": "^0.4.15",
"winston": "^2.3.1"
},
"optionalDependencies": {
"7zip-bin-linux": "^1.1.0",
"7zip-bin-win": "^2.1.1"
},
"devEngines": {
"node": ">=6.x",
"npm": ">=3.x",
"yarn": "0.21.3"
}
}

log of the terminal output:

2017-12-19T10:23:58.455Z – ERROR – net:ERR_CONNECTION_RESET
2017-12-19T11:40:52.112Z – ERROR – net::ERR_NETWORK_CHANGED

node version: 8.4.0

npm version: 5.0.3

on which system do you want to create installers (macOS, Linux or Windows): macOS and Windows

About this issue

  • Original URL
  • State: closed
  • Created 7 years ago
  • Reactions: 18
  • Comments: 39 (6 by maintainers)

Commits related to this issue

Most upvoted comments

Here’s an example of what I got to work for me. I was only able to catch all of them if autoDownload == false.

autoUpdater.autoDownload = false;

function checkForUpdates() {
    autoUpdater.checkForUpdates().then((info) => {
        if (autoUpdater.updateAvailable) {
            downloadUpdate(info.cancellationToken);
        } else {
            log.info('Update not available')
        }
    }).catch((error) => {
        if (isNetworkError(error)) {
            log.info('Network Error');
        } else {
            log.info('Unknown Error');
            log.info(error == null ? "unknown" : (error.stack || error).toString());
        }
    });
}

function downloadUpdate(cancellationToken) {
    autoUpdater.downloadUpdate(cancellationToken).then((file) => {
        setImmediate(() => autoUpdater.quitAndInstall());
    }).catch((error) => {
        if (isNetworkError(error)) {
            log.info('Network Error');
        } else {
            log.info('Unknown Error');
            log.info(error == null ? "unknown" : (error.stack || error).toString());
        }
    });
}

function isNetworkError(errorObject) {
    return errorObject.message === "net::ERR_INTERNET_DISCONNECTED" ||
        errorObject.message === "net::ERR_PROXY_CONNECTION_FAILED" ||
        errorObject.message === "net::ERR_CONNECTION_RESET" ||
        errorObject.message === "net::ERR_CONNECTION_CLOSE" ||
        errorObject.message === "net::ERR_NAME_NOT_RESOLVED" ||
        errorObject.message === "net::ERR_CONNECTION_TIMED_OUT";
}

This really shouldn’t be closed because the bug is still happening. What @thetroy posted is spot on. Applying the patch and listening to the error event on the response fixes the issue of an uncaught error during update download, which else will lead to the application just crashing.

@develar The most reliable way to reproduce the issue is to start updating the Electron application while the computer is connected to the internet via a Wi-Fi network and connect to another network while the update is still in progress

I believe this issue can be closed now that this PR by @vladimiry has been merged and released in electron-updater@4.0.7.

By the way, that PR tweaked only checkForUpdatesAndNotify method but I didn’t explore the checkForUpdates method which also might potentially be a problematic one.

Sounds like #2451. I’d really love to catch them as well, so they don’t end up in Rollbar (which uses uncaughtException). I’m also getting flooded by other errors like ENOSPC: no space left on device or Cannot update while running on a read-only volume, etc.

I don’t know for sure, but it looks like that might be this: https://github.com/electron-userland/electron-builder/blob/9d6eb9602522048597b185c604f02387820aa8d9/packages/electron-updater/src/AppUpdater.ts#L339-L346

Everywhere in AppUpdater that there’s error handling, it emits the error event and re-throw the original error. Given these are async functions, it looks like catching is not possible. I’m not sure why we’d want to throw an error as well as emit the error event.

@btibarra @FantasticFiasco thanks for replying guys. No reply from package developers for now. As a temporary workaround you can try catching errors with process.on(‘uncaughtException’, callback) in your main process or window.onerror = function yourExceptionHandler(msg, url, line, column, error) {}) in a renderer process. Or with Node’s domain api (https://nodejs.org/api/domain.html), but it’s supposed to be deprecated soon and replaced with something else. Not sure how soon though so it might be worth a try 😃 Anyway, hope some of this will help you guys:) Will continue waiting for the devs to reply for now

I managed to deal with it this way. I hope it helps somebody.

try {
   const updateCheckResult = await autoUpdater.checkForUpdates();
   if (updateCheckResult.downloadPromise) {
      updateCheckResult.downloadPromise.catch(error => {
         console.error('Error while downloading the update: ', error);
      });
   }
} catch (error) {
   console.error('Error while on checkForUpdates: ', error);
}

issue is still present for me with autoUpdater.checkForUpdates()

any updates?

If I’m understanding correctly, this issue should be re-opened since a global error handler is still required to catch certain connection exceptions:

autoUpdater.checkForUpdatesAndNotify().catch(err => {
  console.error('[initApp.checkForUpdates] Update failed: ' + err)
})
process.on('uncaughtException', (err) => {
  console.error('[uncaughtException] Whoops! There was an error: ' + err)
})

It would be very helpful if someone could post a simple repository that reliably generates these errors.

Regarding ERR_CONNECTION_RESET, does anyone know if 22.3.5 contains a fix for configurePipes as @thetroy mentioned above?

@tjazak - In what version of auto updater are you using? I don’t have any property autoUpdater.updateAvailable and the UpdateCheckResult object that is returned from autoUpdater.checkForUpdates() doesn’t have any property saying if an update is available or not. Should I manually check the update version with the current one? The documentation in electron-builder doesn’t specify how to use the UpdateCheckResult, it almost looks like they never intended it to be used with promise based approach…