зеркало из https://github.com/electron/electron.git
fix: handle electron script errors better (#25328)
This commit is contained in:
Родитель
29c1248e96
Коммит
4ad9bcb8b5
|
@ -10,10 +10,9 @@ config.output = {
|
||||||
filename: path.basename(outPath)
|
filename: path.basename(outPath)
|
||||||
};
|
};
|
||||||
|
|
||||||
const { wrapInitWithProfilingTimeout } = config;
|
const { wrapInitWithProfilingTimeout, wrapInitWithTryCatch, ...webpackConfig } = config;
|
||||||
delete config.wrapInitWithProfilingTimeout;
|
|
||||||
|
|
||||||
webpack(config, (err, stats) => {
|
webpack(webpackConfig, (err, stats) => {
|
||||||
if (err) {
|
if (err) {
|
||||||
console.error(err);
|
console.error(err);
|
||||||
process.exit(1);
|
process.exit(1);
|
||||||
|
@ -21,9 +20,17 @@ webpack(config, (err, stats) => {
|
||||||
console.error(stats.toString('normal'));
|
console.error(stats.toString('normal'));
|
||||||
process.exit(1);
|
process.exit(1);
|
||||||
} else {
|
} 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) {
|
if (wrapInitWithProfilingTimeout) {
|
||||||
const contents = fs.readFileSync(outPath, 'utf8');
|
contents = `function ___electron_webpack_init__() {
|
||||||
const newContents = `function ___electron_webpack_init__() {
|
|
||||||
${contents}
|
${contents}
|
||||||
};
|
};
|
||||||
if ((globalThis.process || binding.process).argv.includes("--profile-electron-init")) {
|
if ((globalThis.process || binding.process).argv.includes("--profile-electron-init")) {
|
||||||
|
@ -31,8 +38,8 @@ if ((globalThis.process || binding.process).argv.includes("--profile-electron-in
|
||||||
} else {
|
} else {
|
||||||
___electron_webpack_init__();
|
___electron_webpack_init__();
|
||||||
}`;
|
}`;
|
||||||
fs.writeFileSync(outPath, newContents);
|
|
||||||
}
|
}
|
||||||
|
fs.writeFileSync(outPath, contents);
|
||||||
process.exit(0);
|
process.exit(0);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
|
@ -69,7 +69,8 @@ module.exports = ({
|
||||||
loadElectronFromAlternateTarget,
|
loadElectronFromAlternateTarget,
|
||||||
targetDeletesNodeGlobals,
|
targetDeletesNodeGlobals,
|
||||||
target,
|
target,
|
||||||
wrapInitWithProfilingTimeout
|
wrapInitWithProfilingTimeout,
|
||||||
|
wrapInitWithTryCatch
|
||||||
}) => {
|
}) => {
|
||||||
let entry = path.resolve(electronRoot, 'lib', target, 'init.ts');
|
let entry = path.resolve(electronRoot, 'lib', target, 'init.ts');
|
||||||
if (!fs.existsSync(entry)) {
|
if (!fs.existsSync(entry)) {
|
||||||
|
@ -87,6 +88,7 @@ module.exports = ({
|
||||||
filename: `${target}.bundle.js`
|
filename: `${target}.bundle.js`
|
||||||
},
|
},
|
||||||
wrapInitWithProfilingTimeout,
|
wrapInitWithProfilingTimeout,
|
||||||
|
wrapInitWithTryCatch,
|
||||||
resolve: {
|
resolve: {
|
||||||
alias: {
|
alias: {
|
||||||
'@electron/internal': path.resolve(electronRoot, 'lib'),
|
'@electron/internal': path.resolve(electronRoot, 'lib'),
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
module.exports = require('./webpack.config.base')({
|
module.exports = require('./webpack.config.base')({
|
||||||
target: 'isolated_renderer',
|
target: 'isolated_renderer',
|
||||||
alwaysHasNode: false
|
alwaysHasNode: false,
|
||||||
|
wrapInitWithTryCatch: true
|
||||||
});
|
});
|
||||||
|
|
|
@ -2,5 +2,6 @@ module.exports = require('./webpack.config.base')({
|
||||||
target: 'renderer',
|
target: 'renderer',
|
||||||
alwaysHasNode: true,
|
alwaysHasNode: true,
|
||||||
targetDeletesNodeGlobals: true,
|
targetDeletesNodeGlobals: true,
|
||||||
wrapInitWithProfilingTimeout: true
|
wrapInitWithProfilingTimeout: true,
|
||||||
|
wrapInitWithTryCatch: true
|
||||||
});
|
});
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
module.exports = require('./webpack.config.base')({
|
module.exports = require('./webpack.config.base')({
|
||||||
target: 'sandboxed_renderer',
|
target: 'sandboxed_renderer',
|
||||||
alwaysHasNode: false,
|
alwaysHasNode: false,
|
||||||
wrapInitWithProfilingTimeout: true
|
wrapInitWithProfilingTimeout: true,
|
||||||
|
wrapInitWithTryCatch: true
|
||||||
});
|
});
|
||||||
|
|
|
@ -2,5 +2,6 @@ module.exports = require('./webpack.config.base')({
|
||||||
target: 'worker',
|
target: 'worker',
|
||||||
loadElectronFromAlternateTarget: 'renderer',
|
loadElectronFromAlternateTarget: 'renderer',
|
||||||
alwaysHasNode: true,
|
alwaysHasNode: true,
|
||||||
targetDeletesNodeGlobals: true
|
targetDeletesNodeGlobals: true,
|
||||||
|
wrapInitWithTryCatch: true
|
||||||
});
|
});
|
||||||
|
|
|
@ -400,9 +400,24 @@ node::Environment* NodeBindings::CreateEnvironment(
|
||||||
std::unique_ptr<const char*[]> c_argv = StringVectorToArgArray(args);
|
std::unique_ptr<const char*[]> c_argv = StringVectorToArgArray(args);
|
||||||
isolate_data_ =
|
isolate_data_ =
|
||||||
node::CreateIsolateData(context->GetIsolate(), uv_loop_, platform);
|
node::CreateIsolateData(context->GetIsolate(), uv_loop_, platform);
|
||||||
node::Environment* env = node::CreateEnvironment(
|
|
||||||
isolate_data_, context, args.size(), c_argv.get(), 0, nullptr);
|
node::Environment* env;
|
||||||
DCHECK(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
|
// Clean up the global _noBrowserGlobals that we unironically injected into
|
||||||
// the global scope
|
// the global scope
|
||||||
|
|
|
@ -3,6 +3,7 @@
|
||||||
// found in the LICENSE file.
|
// found in the LICENSE file.
|
||||||
|
|
||||||
#include "shell/common/node_util.h"
|
#include "shell/common/node_util.h"
|
||||||
|
#include "base/logging.h"
|
||||||
#include "shell/common/node_includes.h"
|
#include "shell/common/node_includes.h"
|
||||||
#include "third_party/electron_node/src/node_native_module_env.h"
|
#include "third_party/electron_node/src/node_native_module_env.h"
|
||||||
|
|
||||||
|
@ -17,6 +18,7 @@ v8::MaybeLocal<v8::Value> CompileAndCall(
|
||||||
std::vector<v8::Local<v8::Value>>* arguments,
|
std::vector<v8::Local<v8::Value>>* arguments,
|
||||||
node::Environment* optional_env) {
|
node::Environment* optional_env) {
|
||||||
v8::Isolate* isolate = context->GetIsolate();
|
v8::Isolate* isolate = context->GetIsolate();
|
||||||
|
v8::TryCatch try_catch(isolate);
|
||||||
v8::MaybeLocal<v8::Function> compiled =
|
v8::MaybeLocal<v8::Function> compiled =
|
||||||
node::native_module::NativeModuleEnv::LookupAndCompile(
|
node::native_module::NativeModuleEnv::LookupAndCompile(
|
||||||
context, id, parameters, optional_env);
|
context, id, parameters, optional_env);
|
||||||
|
@ -24,8 +26,14 @@ v8::MaybeLocal<v8::Value> CompileAndCall(
|
||||||
return v8::MaybeLocal<v8::Value>();
|
return v8::MaybeLocal<v8::Value>();
|
||||||
}
|
}
|
||||||
v8::Local<v8::Function> fn = compiled.ToLocalChecked().As<v8::Function>();
|
v8::Local<v8::Function> fn = compiled.ToLocalChecked().As<v8::Function>();
|
||||||
return fn->Call(context, v8::Null(isolate), arguments->size(),
|
v8::MaybeLocal<v8::Value> ret = fn->Call(
|
||||||
arguments->data());
|
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
|
} // namespace util
|
||||||
|
|
Загрузка…
Ссылка в новой задаче