Skip to content

Commit

Permalink
fix: handle electron script errors better (#25331) (#25453)
Browse files Browse the repository at this point in the history
Co-authored-by: Samuel Attard <samuel.r.attard@gmail.com>

Co-authored-by: trop[bot] <37223003+trop[bot]@users.noreply.github.com>
  • Loading branch information
MarshallOfSound and trop[bot] committed Sep 14, 2020
1 parent 48779fe commit fe85a94
Show file tree
Hide file tree
Showing 8 changed files with 51 additions and 15 deletions.
19 changes: 13 additions & 6 deletions build/webpack/run-compiler.js
Expand Up @@ -10,29 +10,36 @@ config.output = {
filename: path.basename(outPath)
}

const { wrapInitWithProfilingTimeout } = config;
delete config.wrapInitWithProfilingTimeout;
const { wrapInitWithProfilingTimeout, wrapInitWithTryCatch, ...webpackConfig } = config;

webpack(config, (err, stats) => {
webpack(webpackConfig, (err, stats) => {
if (err) {
console.error(err)
process.exit(1)
} else if (stats.hasErrors()) {
console.error(stats.toString('normal'))
process.exit(1)
} else {
let contents = fs.readFileSync(outPath, 'utf8');
if (wrapInitWithTryCatch) {
contents = `try {
${contents}
} catch (err) {
console.error('Electron ${webpackConfig.output.filename} script failed to run');
console.error(err);
}`;
}
if (wrapInitWithProfilingTimeout) {
const contents = fs.readFileSync(outPath, 'utf8');
const newContents = `function ___electron_webpack_init__() {
contents = `function ___electron_webpack_init__() {
${contents}
};
if ((globalThis.process || binding.process).argv.includes("--profile-electron-init")) {
setTimeout(___electron_webpack_init__, 0);
} else {
___electron_webpack_init__();
}`;
fs.writeFileSync(outPath, newContents);
}
fs.writeFileSync(outPath, contents)
process.exit(0)
}
})
4 changes: 3 additions & 1 deletion build/webpack/webpack.config.base.js
Expand Up @@ -86,7 +86,8 @@ module.exports = ({
loadElectronFromAlternateTarget,
targetDeletesNodeGlobals,
target,
wrapInitWithProfilingTimeout
wrapInitWithProfilingTimeout,
wrapInitWithTryCatch
}) => {
let entry = path.resolve(electronRoot, 'lib', target, 'init.ts')
if (!fs.existsSync(entry)) {
Expand All @@ -102,6 +103,7 @@ module.exports = ({
filename: `${target}.bundle.js`
},
wrapInitWithProfilingTimeout,
wrapInitWithTryCatch,
resolve: {
alias: {
'@electron/internal': path.resolve(electronRoot, 'lib'),
Expand Down
3 changes: 2 additions & 1 deletion build/webpack/webpack.config.isolated_renderer.js
@@ -1,4 +1,5 @@
module.exports = require('./webpack.config.base')({
target: 'isolated_renderer',
alwaysHasNode: false
alwaysHasNode: false,
wrapInitWithTryCatch: true
})
3 changes: 2 additions & 1 deletion build/webpack/webpack.config.renderer.js
Expand Up @@ -2,5 +2,6 @@ module.exports = require('./webpack.config.base')({
target: 'renderer',
alwaysHasNode: true,
targetDeletesNodeGlobals: true,
wrapInitWithProfilingTimeout: true
wrapInitWithProfilingTimeout: true,
wrapInitWithTryCatch: true
})
1 change: 1 addition & 0 deletions build/webpack/webpack.config.sandboxed_renderer.js
Expand Up @@ -2,4 +2,5 @@ module.exports = require('./webpack.config.base')({
target: 'sandboxed_renderer',
alwaysHasNode: false,
wrapInitWithProfilingTimeout: true,
wrapInitWithTryCatch: true
})
3 changes: 2 additions & 1 deletion build/webpack/webpack.config.worker.js
Expand Up @@ -2,5 +2,6 @@ module.exports = require('./webpack.config.base')({
target: 'worker',
loadElectronFromAlternateTarget: 'renderer',
alwaysHasNode: true,
targetDeletesNodeGlobals: true
targetDeletesNodeGlobals: true,
wrapInitWithTryCatch: true
})
21 changes: 18 additions & 3 deletions shell/common/node_bindings.cc
Expand Up @@ -342,9 +342,24 @@ node::Environment* NodeBindings::CreateEnvironment(
std::unique_ptr<const char*[]> c_argv = StringVectorToArgArray(args);
isolate_data_ =
node::CreateIsolateData(context->GetIsolate(), uv_loop_, platform);
node::Environment* env = node::CreateEnvironment(
isolate_data_, context, args.size(), c_argv.get(), 0, nullptr);
DCHECK(env);

node::Environment* env;
if (browser_env_ != BrowserEnvironment::BROWSER) {
v8::TryCatch try_catch(context->GetIsolate());
env = node::CreateEnvironment(isolate_data_, context, args.size(),
c_argv.get(), 0, nullptr);
DCHECK(env);
// This will only be caught when something has gone terrible wrong as all
// electron scripts are wrapped in a try {} catch {} in run-compiler.js
if (try_catch.HasCaught()) {
LOG(ERROR) << "Failed to initialize node environment in process: "
<< process_type;
}
} else {
env = node::CreateEnvironment(isolate_data_, context, args.size(),
c_argv.get(), 0, nullptr);
DCHECK(env);
}

// Clean up the global _noBrowserGlobals that we unironically injected into
// the global scope
Expand Down
12 changes: 10 additions & 2 deletions shell/common/node_util.cc
Expand Up @@ -3,6 +3,7 @@
// found in the LICENSE file.

#include "shell/common/node_util.h"
#include "base/logging.h"
#include "shell/common/node_includes.h"
#include "third_party/electron_node/src/node_native_module_env.h"

Expand All @@ -17,15 +18,22 @@ v8::MaybeLocal<v8::Value> CompileAndCall(
std::vector<v8::Local<v8::Value>>* arguments,
node::Environment* optional_env) {
v8::Isolate* isolate = context->GetIsolate();
v8::TryCatch try_catch(isolate);
v8::MaybeLocal<v8::Function> compiled =
node::native_module::NativeModuleEnv::LookupAndCompile(
context, id, parameters, optional_env);
if (compiled.IsEmpty()) {
return v8::MaybeLocal<v8::Value>();
}
v8::Local<v8::Function> fn = compiled.ToLocalChecked().As<v8::Function>();
return fn->Call(context, v8::Null(isolate), arguments->size(),
arguments->data());
v8::MaybeLocal<v8::Value> ret = fn->Call(
context, v8::Null(isolate), arguments->size(), arguments->data());
// This will only be caught when something has gone terrible wrong as all
// electron scripts are wrapped in a try {} catch {} in run-compiler.js
if (try_catch.HasCaught()) {
LOG(ERROR) << "Failed to CompileAndCall electron script: " << id;
}
return ret;
}

} // namespace util
Expand Down

0 comments on commit fe85a94

Please sign in to comment.