react-native-fabric icon indicating copy to clipboard operation
react-native-fabric copied to clipboard

Log JavaScript errors / stack traces?

Open corymsmith opened this issue 8 years ago • 30 comments

corymsmith avatar Jan 22 '16 23:01 corymsmith

Check out https://medium.com/delivery-com-engineering/add-crashlytics-to-your-react-native-ios-app-69a983a9062a

lrettig avatar Feb 10 '16 16:02 lrettig

This should be covered by #14

corymsmith avatar Mar 14 '16 16:03 corymsmith

Just to clarify, we have to follow the article posted by @lrettig in order to catch JS errors with this library, am I right?

alvaromb avatar Mar 30 '16 07:03 alvaromb

Yes. This library adds the ability to pass user info (username, etc.) to Crashlytics from JS, to test crashing from JS, and to record non-fatal JS errors using Crashlytics. @corymsmith the main README should probably be updated to reflect this, what do you think?

lrettig avatar Mar 30 '16 11:03 lrettig

Any update on this? This is the only reason I want this library- to get the stack trace, and line of the JavaScript error.

quincycs avatar Apr 21 '16 11:04 quincycs

Hi @quincycs -- as outlined in this issue, the library should already support what you need. Just make sure you follow the steps in the blog post mentioned above (https://medium.com/delivery-com-engineering/add-crashlytics-to-your-react-native-ios-app-69a983a9062a) as well (still to be documented properly here, I think). Let me know if I'm missing something.

lrettig avatar Apr 22 '16 08:04 lrettig

@lrettig thx! But how about fatal JS errors? It really gives the JS line number? (If so that is awesomeee)

quincycs avatar Apr 22 '16 14:04 quincycs

Seems the only missing piece to the puzzle is the last part of the blog where all the crash groups just one. I don't really understand that if we are logging the fatal crash from JS. I see it as ... Here's the complete data of the crash generated at crash time...library send this to crashlytics

quincycs avatar Apr 22 '16 14:04 quincycs

@quincycs yes, you get the line number (screenshot here: https://github.com/corymsmith/react-native-fabric/issues/8#issuecomment-183426906), but keep in mind that when running in production mode, you'll get minified code and line numbers corresponding to the minified code. You can run this through a source map script to map back to the original code--I think that's outlined the comments for the blog post discussed here.

The crashes all get grouped together since Crashlytics shows the place in the native code where the crash happened, which is always going to be the same when trapping JS errors. I don't yet know of a workaround for this; in my apps it's not a big issue since Crashlytics will continue to report new errors even after you mark one as complete (they'll appear as "issue regression" in future releases).

You can use this library to trap fatal JS errors. In my case, I just wrap all sensitive code in a try... catch block (actually, I use promises). There's more discussion of a way to do this globally here: https://github.com/facebook/react-native/issues/1194

lrettig avatar Apr 24 '16 10:04 lrettig

@lrettig did you managed to get sourcemap working? RN Packager bundles sourcemap as separate file - and we don't have filesystem access in RN by default. So sourcemap should be inlined via base64.

I tried to use https://github.com/evanw/node-source-map-support , but no luck. I tried with separate sourcemap file and inlined one

I used this self-written script for inlining sourcemap:

#!/usr/bin/env node

var fs    = require('fs');
var path  = require('path');

var convert = require('convert-source-map');

function embedSourceMap (file) {

  var source = fs.readFileSync(file, 'utf8');

  var sourcemapComment = convert
    .fromMapFileComment(source, path.dirname(file))
    .toComment();

  var patched = source.replace(convert.mapFileCommentRegex, sourcemapComment);

  fs.writeFileSync(file + '.bak', source);
  fs.writeFileSync(file, patched);

}

process.argv.slice(2).forEach(embedSourceMap);

I also checked source maps in Google Chrome, loading my script in html. Os course, it's failing to work, but I can see sources with separate source map file and inlined one. So, source map is working.

But error stack... Everything I've got in adb logcat is : index.android.bundle:32 or <unknown>@11:32, which is unhelpful

I really need to see full error stack :(

ColCh avatar May 07 '16 11:05 ColCh

I did, after a fashion. I followed How to added sourcemap in React Native for Production? and wrote a separate script that, on a one-off basis, allows me to convert the unmapped code location to a mapped location. But this is far short of remapping an entire stack trace. I don't think that would be terribly hard to do; it would be awesome if this library could automatically remap the stack trace for you.

lrettig avatar May 07 '16 16:05 lrettig

I haven't look into that at all but agree it's something that would be ideal in this lib!

On May 7, 2016, 10:57 AM -0600, Lane [email protected], wrote:

I did, after a fashion. I followedHow to added sourcemap in React Native for Production?(http://stackoverflow.com/questions/34715106/how-to-added-sourcemap-in-react-native-for-production/34733906#34733906)and wrote a separate script that, on a one-off basis, allows me to convert the unmapped code location to a mapped location. But this is far short of remapping an entire stack trace. I don't think that would be terribly hard to do; it would be awesome if this library could automatically remap the stack trace for you.

— You are receiving this because you were mentioned. Reply to this email directly orview it on GitHub(https://github.com/corymsmith/react-native-fabric/issues/2#issuecomment-217651856)

corymsmith avatar May 07 '16 17:05 corymsmith

What about android? The article posted is iOS only.

ashleydw avatar May 10 '16 07:05 ashleydw

@ashleydw Check the StackOverflow link that @lrettig posted above

corymsmith avatar May 10 '16 14:05 corymsmith

@lrettig thanks. Work with sourcemap - this means this lib should read script file, read separate sourcemap, consume it, and only then you will be able to get mapped stack trace to real code.

This means:

  1. You should have file read permission on RN (of course, we don't have any. fs module for RN is separate project, which is maintained by community. RN moves fast, so may be it will be hard to keep it up to date with latest version
  2. You should upload your sourcemap with production version of the app. Yes, anybody can apktool d your .apk, get .js and .js.map files out and "unobfuscate" your app to working js source. Not everyone will like this!

So, I read your message twice and decided, that the best approach will be:

  1. (this is for deploy builds : test [ like Alpha, Beta and TestFlight] and prod [App Store, Google Play]
  2. Generate .js with .js.map
  3. Copy and organize it (you have build number 123 and build version 1.0.0 for each deploy version of the app)
  4. Remove .js.map file to prevent it dropping into deploy app archive

When you experience an error in Crashlytics, you:

  1. Get your unmapped stacktrace (<unknown>:32:23 and so on)
  2. Find corresponding .js with .js.map for crashed app version (app versions are on Crashlytics)
  3. Use self-written script to locate "source-mapped" sources

Pretty overwhelming, but it will work... Any another ideas on this? It's will be great to see something on this point.

Of course, Github Issue is not approtiate place for duscussion on this (or not?), but I haven't found any place on the internet. I don't like chats - I know, that some day, some dev will face this trouble like I and will found our discussion to find answers.

ColCh avatar May 10 '16 16:05 ColCh

@corymsmith I can't see a relevant stackoverflow post.

I have android fully working with crashlytics, but I can't see a way of overriding the logging functions as done in the medium post regarding ios.

ashleydw avatar May 10 '16 18:05 ashleydw

@ashleydw I think he was referring to this one: http://stackoverflow.com/questions/34715106/how-to-added-sourcemap-in-react-native-for-production/34733906#34733906

@ColCh I haven't had time to think about this in great depth, but I agree in principle with your proposed approach. I think it would be very cool if this library supported that. Much better than doing it by hand as I've been doing!

lrettig avatar May 24 '16 18:05 lrettig

@lrettig right, but it's ios only

ashleydw avatar May 25 '16 05:05 ashleydw

Hi, guys. I'm using a wrapper based on this lib to create issue, capture un-handled error, log, and set user info and attributes. see the gist Error Report with fabric/crashlytics and react-native Hopes that help someone!

tianjianchn avatar Jul 06 '16 02:07 tianjianchn

@kiliwalk Thanks! But, how do I use it?

wootwoot1234 avatar Sep 20 '16 18:09 wootwoot1234

@kiliwalk could u please send a PR to enable this?

sibelius avatar Jan 27 '17 19:01 sibelius

For people searching for a tool to translate error stacks: https://github.com/SoftwareMansion/stack-beautifier

example:

2017-02-11 15:13:06.477 foo-project[26049:3497670] *** Terminating app due to uncaught exception 'RCTFatalException: Unhandled JS Exception: TEST', reason: 'Unhandled JS Exception: TEST, stack:
<unknown>@476:1189
n@2:545
<unknown>@365:567
n@2:545
<unknown>@12:38
n@2:545
i@2:266
global code@481:9
'

to translate it, source map file should be provided

➜  foo-project stack-beautifier ios/main.jsbundle.map <<EOF
Unhandled JS Exception: TEST', reason: 'Unhandled JS Exception: TEST, stack:
<unknown>@476:1189
n@2:545
<unknown>@365:567
n@2:545
<unknown>@12:38
n@2:545
i@2:266
global code@481:9
EOF
Unhandled JS Exception: TEST', reason: 'Unhandled JS Exception: TEST, stack:
at /foo-project/src/utils/log.js:56:16
at global (/foo-project/node_modules/react-native/packager/react-packager/src/Resolver/polyfills/require.js:171:12)
at /foo-project/src/app.js:45:10
at global (/foo-project/node_modules/react-native/packager/react-packager/src/Resolver/polyfills/require.js:171:12)
at /foo-project/index.ios.js:10:0
at global (/foo-project/node_modules/react-native/packager/react-packager/src/Resolver/polyfills/require.js:171:12)
at moduleId (/foo-project/node_modules/react-native/packager/react-packager/src/Resolver/polyfills/require.js:116:45)
at require-0.js:1:0

and /foo-project/src/utils/log.js:56:16 is throw new Error("TEST");

ColCh avatar Feb 11 '17 12:02 ColCh

@tianjianchn your link above is dead I need to see un-minified stack trace. can someone please share?

onpaws avatar Mar 11 '17 01:03 onpaws

@onpaws Sorry. Updated the link in my previous comment, or see here. Currently I'm trying to use another bug tracker(snag-react-native)

tianjianchn avatar Mar 11 '17 09:03 tianjianchn

How is Bugsnag working for you?

antoinerousseau avatar Mar 12 '17 14:03 antoinerousseau

I just set it up. I couldn't get it to work quite right in development mode but in production mode with all the asset files uploaded it seems to work pretty well. Check back with me in a week if you want an update.

wootwoot1234 avatar Mar 12 '17 21:03 wootwoot1234

I know it's been a bit more than a week 😉 but @wootwoot1234 any update on @tianjianchn proposed solution? Are you still using it?

kelset avatar Aug 03 '17 11:08 kelset

@kelset after using it for a while fabric didn't work for me. I ended up switching to BugSnag. When I switched over, the support for react native was much better and their tech support is really good too.

wootwoot1234 avatar Aug 03 '17 16:08 wootwoot1234

So there's no official solution for this issue yet? What workaround do you guys use (if you do for sure) for handling error with stack trace? @ColCh's method works pretty good but built-in solution would be much better instead of this for sure. What about building stack trace map in root component and using it as translator for following error report to crashlytics?

igorarkhipenko avatar Jan 22 '18 22:01 igorarkhipenko

Any update on this? We should at least implement something?

evanjmg avatar Apr 08 '19 15:04 evanjmg