Sentry-javascript: Help using in Universal/Isomorphic app

Created on 3 May 2017  ·  13Comments  ·  Source: getsentry/sentry-javascript

Hi,
I'm working in a project based on next.js, a universal framework to build apps, and I appreciate some help/ideas to solve a problem.

I use express too, with the raven-node client, but for the "client" app I need raven-js, the problem is due the framework is universal it also does server-side-rendering of my components. The problem is if an error ocurrs while SSR raven-js fails due XMLHttpRequest is not defined.

Does has it sense to change the whatwg-fetchto isomorphic-fetch so it works universally?

Most helpful comment

Thank you sentry team for your consideration on this issue. Having isomorphic support would help the massive next.js community become sentry users.

All 13 comments

@acanimal I'm doing exactly the same thing as what you're intending to do (except without next but just with regular react). See my repo for the way I've made it work here: https://github.com/ismay/ismaywolff.nl. And yes, I'm using isomorphic-fetch.

@ismay can you make a short summary or point me to the right files? Thanks

Well I'm not exactly sure what you're running into, but here's what I'm doing (which I think would work in your situation as well):

Error reporting works for me both client and serverside. I haven't run into the XMLHttpRequest error that you describe. Might be due to isomorphic-fetch, which I am using.

With the new @sentry/node and @sentry/browser packages, how are we supposed to handle code that can be run on the server or the client (ismorphic)?

@davidfurlong I think there is no super easy solution for this. @sentry/browser should also run in node, but you will probably miss some of the hooks we attach to in @sentry/node.
The correct way would be to write a standalone SDK like https://github.com/getsentry/sentry-electron

I did this:

import {
  configureScope as configureBrowserScope,
  captureMessage as browserCaptureMessage,
} from '@sentry/browser';
import {
  configureScope as configureNodeScope,
  captureMessage as nodeCaptureMessage,
} from '@sentry/node';

// TODO: figure out whether this is actually okay.
// NOTE: process.env.BROWSER is being provided by webpack's DefinePlugin in this case.
export const configureScope = process.env.BROWSER ? configureBrowserScope : configureNodeScope;
export const captureMessage = process.env.BROWSER ? browserCaptureMessage : nodeCaptureMessage;

The jury's still out on whether it's a dumb idea. My understanding of ES6 exports is that you don't want to make them conditional, because you want them to be statically analyzable, but I think this should have the desired effect?

Weeeell, yes, it'll work, but it'll bundle both packages in your file. Unless you tree-shake them with rollup or something :)

Yeah... and I found that it really doesn't work that well, because the node packages expect fs to be available, so it fails in the client bundle import.

Hopefully tree-shaking does its thing :man_shrugging:

Thank you sentry team for your consideration on this issue. Having isomorphic support would help the massive next.js community become sentry users.

This won't really work as node and browser versions have different useful plugins. I think a necessary solution is aliasing in webpack like here: https://github.com/zeit/next.js/issues/1852

Also interested in an isomorphic solution, tried to load raven on the server side only, using "require" and not "import" but it still causes issues somehow like: (Using Next 5)

ModuleNotFoundError: Module not found: Error: Can't resolve 'console' in '/Users/vadorequest/dev/loan-advisor/node_modules/raven/lib/instrumentation'
    at factoryCallback (/Users/vadorequest/dev/loan-advisor/node_modules/next/node_modules/webpack/lib/Compilation.js:276:40)
    at factory (/Users/vadorequest/dev/loan-advisor/node_modules/next/node_modules/webpack/lib/NormalModuleFactory.js:235:20)
    at resolver (/Users/vadorequest/dev/loan-advisor/node_modules/next/node_modules/webpack/lib/NormalModuleFactory.js:60:20)
    at asyncLib.parallel.e (/Users/vadorequest/dev/loan-advisor/node_modules/next/node_modules/webpack/lib/NormalModuleFactory.js:127:20)
    at /Users/vadorequest/dev/loan-advisor/node_modules/async/dist/async.js:3888:9
    at /Users/vadorequest/dev/loan-advisor/node_modules/async/dist/async.js:473:16
    at iteratorCallback (/Users/vadorequest/dev/loan-advisor/node_modules/async/dist/async.js:1062:13)
    at /Users/vadorequest/dev/loan-advisor/node_modules/async/dist/async.js:969:16
    at /Users/vadorequest/dev/loan-advisor/node_modules/async/dist/async.js:3885:13
    at resolvers.normal.resolve (/Users/vadorequest/dev/loan-advisor/node_modules/next/node_modules/webpack/lib/NormalModuleFactory.js:119:22)
    at onError (/Users/vadorequest/dev/loan-advisor/node_modules/enhanced-resolve/lib/Resolver.js:65:10)
    at loggingCallbackWrapper (/Users/vadorequest/dev/loan-advisor/node_modules/enhanced-resolve/lib/createInnerCallback.js:31:19)
    at runAfter (/Users/vadorequest/dev/loan-advisor/node_modules/enhanced-resolve/lib/Resolver.js:158:4)
    at innerCallback (/Users/vadorequest/dev/loan-advisor/node_modules/enhanced-resolve/lib/Resolver.js:146:3)
    at loggingCallbackWrapper (/Users/vadorequest/dev/loan-advisor/node_modules/enhanced-resolve/lib/createInnerCallback.js:31:19)
    at next (/Users/vadorequest/dev/loan-advisor/node_modules/tapable/lib/Tapable.js:252:11)

Well I'm not exactly sure what you're running into, but here's what I'm doing (which I think would work in your situation as well):

Error reporting works for me both client and serverside. I haven't run into the XMLHttpRequest error that you describe. Might be due to isomorphic-fetch, which I am using.

where is repo

I'll close this issue for triaging purposes, as it's too generic. Please feel free to create a new one with more concrete examples/questions so we can work on resolving them.

Was this page helpful?
0 / 5 - 0 ratings