Open stoefln opened 6 days ago
Assigning to @getsentry/support for routing ⏲️
Routing to @getsentry/product-owners-issues for triage ⏲️
Which version of Electron are you using?
Have you followed the migration docs around importing the SDK to init it in each process?
@timfish electron 12.2.3 and yes, i have imported sentry just as in the docs
electron 12.2.3
Ah that is likely the issue.
For v5 of the SDK, the minimum Electron version has to be increased to v15 due to the required Node version.
Out of interest, what's blocking your update to a newer Electron version? Personally, I've got an app stuck on v18 because we need to migrate away from ffi-napi
.
After upgrade to electron 16 I am still getting this error:
Module not found: Error: Can't resolve 'opentelemetry-instrumentation-fetch-node' in '/Users/me/Workspace/myapp/node_modules/@sentry/node/cjs/integrations'
@ ./node_modules/@sentry/node/cjs/index.js 4:18-57
@ ./app/lib/ErrorReporting.js 281:16-39
@ ./app/main.js 14:0-82 24:0-26 25:0-11
opentelemetry-instrumentation-fetch-node
is an optional dependency of @sentry/node
which is loaded asynchronously if it has been added as a dependency.
Can you share more of your Sentry initialisation code and webpack config? We don't see this error in our webpack integration tests!
index.js (main process):
import * as Sentry from "@sentry/electron/main";
Sentry.init(getMainConfig(app.getVersion()))
function getMainConfig(version) {
const Sentry = require('@sentry/electron/main')
const config = getConfig(version)
const mainConfig = {
...config,
attachScreenshot: true
}
return mainConfig
}
function getConfig(version) {
return {
// changed for 1.4. and up. Changing this dsn from major release to major release will allow us to switch off error reporting for older versions.
// new DSNs can be created here: https://...sentry.io/settings/projects/.../keys/
dsn: 'https://6bf63d16f4d24...',
release: 'Repeato-' + version,
debug: isDev,
beforeBreadcrumb(breadcrumb) {
// remove additional data if only 1 argument was passed to console - avoid redundant data
if (breadcrumb.category === 'console' && breadcrumb.data?.arguments?.length === 1) delete breadcrumb.data
return breadcrumb
}
}
}
app.js (renderer):
import * as Sentry from "@sentry/electron/renderer"
initRendererErrorReporting(Sentry).catch(console.error)
async function initRendererErrorReporting(_sentry) {
const electron = await import('electron')
const version = electron.remote.app.getVersion()
console.log('initRendererErrorReporting', _sentry)
Sentry = _sentry
if (!isDev) {
Sentry.init(getRendererConfig(version))
}
const logError = log.error
log.error = function () {
var args = Array.prototype.slice.call(arguments)
const error = reduceConsoleArgs(args)
handleError(Sentry, error)
return logError.apply(log, args)
}
var consoleError = console.error
console.error = function () {
var args = Array.prototype.slice.call(arguments)
const error = reduceConsoleArgs(args)
handleError(Sentry, error)
return consoleError.apply(console, args)
}
}
function getRendererConfig(version) {
const config = getConfig(version)
const integrations = []
const rendererConfig = {
...config,
// This sets the sample rate to be 10%. You may want this to be 100% while
// in development and sample at a lower rate in production
replaysSessionSampleRate: 0.1,
// If the entire session is not sampled, use the below sample rate to sample
// sessions when an error occurs.
replaysOnErrorSampleRate: 0.1,
integrations
}
return rendererConfig
}
webpack.entrypoint.config.mjs (for main process):
import path from 'path'
import webpack from 'webpack'
import nodeExternals from 'webpack-node-externals'
import __dirname from './app/utils/dirname.mjs'
export default {
devtool: 'source-map',
entry: ['@babel/polyfill', './index.js'],
mode: 'development',
output: {
filename: 'index-bundle.js',
path: path.resolve(__dirname, 'static')
//clean: true
},
module: {
noParse: /iconv-loader\.js/,
rules: [
{
test: /\.node$/,
use: 'node-loader'
},
{
test: /\.js$/,
exclude: /(node_modules|bower_components)/,
use: ['babel-loader']
}
]
},
plugins: [
new webpack.DefinePlugin({
'process.env.NODE_ENV': JSON.stringify('development')
}),
new webpack.EnvironmentPlugin({
NODE_ENV: 'development',
DEBUG_PROD: false,
START_MINIMIZED: false,
E2E_BUILD: false
})
],
target: 'electron12.2-main',
resolve: {
fallback: {
// Provide polyfills or mocks for node modules used in the browser if necessary
}
},
externals: [
nodeExternals({
allowlist: /\.css$/
})
],
experiments: {
// Future Webpack features can be enabled here
},
infrastructureLogging: {
// This can help in debugging and logging module resolution
level: 'info'
}
}
webpack.config.js (for renderer process)
import { existsSync } from 'fs'
import path from 'path'
import webpack from 'webpack'
import ReactRefreshWebpackPlugin from '@pmmmwh/react-refresh-webpack-plugin'
import __dirname from './app/utils/dirname.mjs'
import { BundleAnalyzerPlugin } from 'webpack-bundle-analyzer'
const buildWorker = existsSync('./app/worker/worker.js')
console.log(`Build worker:`, buildWorker)
//, new BundleAnalyzerPlugin()
const plugins = [new ReactRefreshWebpackPlugin()]
if (!buildWorker) {
plugins.push(new webpack.IgnorePlugin({ resourceRegExp: /TemplateMatcherWorker/ }))
plugins.push(new webpack.IgnorePlugin({ resourceRegExp: /OcrWorker/ }))
plugins.push(new webpack.IgnorePlugin({ resourceRegExp: /ObjectFinder$/ }))
}
const devServerFilePath = path.join(__dirname, 'static')
console.log(`Dev server file path: ${devServerFilePath}`)
/**
* @type {import('webpack').Configuration}
*/
const config = {
devtool: 'eval-cheap-module-source-map',
entry: {
main: ['@babel/polyfill', './app/main.js'],
pdfexport: ['@babel/polyfill', './app/pdfExport.js'],
loading: ['@babel/polyfill', './app/loading.js'],
...(buildWorker && { worker: ['@babel/polyfill', './app/worker/worker.js'] })
},
mode: 'development',
output: {
filename: '[name]-bundle.js',
path: path.resolve(__dirname, 'dist'),
publicPath: '/'
},
module: {
rules: [
{
test: /\.node$/,
use: 'node-loader'
},
{
test: /\.(ts|tsx)$/,
exclude: /node_modules/,
use: 'ts-loader'
},
{
test: /\.js$/,
exclude: /(node_modules|bower_components)\/(?!(aws-sdk|@aws-sdk|@smithy)\/).*/,
use: {
loader: 'babel-loader',
options: {
presets: ['@babel/preset-env']
}
}
},
{
test: /\.mjs$/,
include: /node_modules/,
type: 'javascript/auto'
},
{
test: /\.css$/,
use: ['style-loader', 'css-loader']
},
{
test: /\.(asset)$/i,
use: [
{
loader: 'file-loader',
options: {
name: '[name]'
}
}
]
}
]
},
plugins,
externals: {
'monaco-editor': 'monaco-editor'
},
resolve: {
extensions: ['.ts', '.tsx', '.js', '.jsx']
},
devServer: {
host: 'localhost',
port: process.env.PORT || 3000,
historyApiFallback: true,
hot: true,
static: {
directory: devServerFilePath
}
},
target: 'electron12.2-renderer',
watchOptions: {
poll: 1000,
ignored: ['node_modules/**'],
aggregateTimeout: 600
}
}
export default config
Since the issue is only with the main process, I've only looked at those relevant files.
In our tests we use target: "electron-main"
but we have a much more basic config. electron12.2-main
might be causing issues? Also, since this in the main process, with the correct target
, you should not need to include anything for externals
, so nodeExternals({allowlist: /\.css$/})
seems unnecessary here.
Which version of webpack are you using? If you can point me to a repository that reproduces the issue I can debug this and probably give more guidance.
Upgrading from @sentry/electron v4 to v5 is not possible for me.
Environment
SaaS (https://sentry.io/)
Steps to Reproduce
Expected Result
No error is thrown
Actual Result
-> Error is thrown in renderer thread:
-> Error is thrown in main thread:
Product Area
Unknown
Link
https://stephan-petzl.sentry.io/
DSN
https://stephan-petzl.sentry.io/issues/?project=1554144
Version
No response