├── .gitignore ├── README.md ├── LICENSE ├── package.json └── index.js /.gitignore: -------------------------------------------------------------------------------- 1 | node_modules/ -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | 2 | react-native-fabric-crashlytics 3 | =============================== 4 | 5 | Reports javascript exceptions in React Native to the Crashlytics server, using the react-native-fabric library. 6 | 7 | Usage 8 | ----- 9 | 10 | To use, add this code to your index.ios.js and index.android.js (or some library included by both). 11 | 12 | ``` 13 | // Already assumes that Fabric is initialized/configured properly in the iOS and Android app startup code. 14 | import crashlytics from 'react-native-fabric-crashlytics'; 15 | crashlytics.init(); 16 | ``` -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | ISC License 2 | 3 | Copyright (c) [year(s)], [copyright holder] 4 | 5 | Permission to use, copy, modify, and/or distribute this software for any purpose with or without fee is hereby granted, provided that the above copyright notice and this permission notice appear in all copies. 6 | 7 | THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 8 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "react-native-fabric-crashlytics", 3 | "version": "0.1.8", 4 | "description": "", 5 | "main": "index.js", 6 | "scripts": { 7 | "test": "echo \"Error: no test specified\" && exit 1" 8 | }, 9 | "files": [ 10 | "index.js" 11 | ], 12 | "bugs": { 13 | "url": "https://github.com/mikelambert/react-native-fabric-crashlytics/issues" 14 | }, 15 | "repository": { 16 | "type": "git", 17 | "url": "git+ssh://git@github.com/mikelambert/react-native-fabric-crashlytics.git" 18 | }, 19 | "maintainers": [ 20 | { 21 | "email": "mlambert@gmail.com", 22 | "name": "Mike Lambert" 23 | } 24 | ], 25 | "keywords": [ 26 | "react-native", 27 | "react-component", 28 | "react-native-component", 29 | "react", 30 | "mobile", 31 | "ios", 32 | "android", 33 | "fabric", 34 | "crashlytics" 35 | ], 36 | "author": "", 37 | "license": "ISC", 38 | "dependencies": { 39 | "lodash.assign": "^4.2.0", 40 | "stacktrace-js": "^1.1.0" 41 | }, 42 | "peerDependencies": { 43 | "react-native-fabric": "*" 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /index.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | import { Platform } from 'react-native'; 4 | import StackTrace from 'stacktrace-js'; 5 | import { Crashlytics } from 'react-native-fabric'; 6 | var assign = require('lodash.assign'); 7 | 8 | function init() { 9 | if (__DEV__) { 10 | // Don't send exceptions from __DEV__, it's way too noisy! 11 | // Live reloading and hot reloading in particular lead to tons of noise... 12 | return; 13 | } 14 | 15 | var originalHandler = global.ErrorUtils.getGlobalHandler(); 16 | function errorHandler(e, isFatal) { 17 | StackTrace.fromError(e, {offline: true}).then((x) => { 18 | Crashlytics.recordCustomExceptionName(e.message, e.message, x.map((row) => (assign({}, row, { 19 | fileName: `${row.fileName}:${row.lineNumber || 0}:${row.columnNumber || 0}`, 20 | })))) 21 | }); 22 | // And then re-throw the exception with the original handler 23 | if (originalHandler) { 24 | if (Platform.OS === 'ios') { 25 | originalHandler(e, isFatal); 26 | } else { 27 | // On Android, throwing the original exception immediately results in the 28 | // recordCustomExceptionName() not finishing before the app crashes and therefore not logged 29 | // Add a delay to give it time to log the custom JS exception before crashing the app. 30 | // The user facing effect of this delay is that separate JS errors will appear as separate 31 | // issues in the Crashlytics dashboard. 32 | setTimeout(() => { 33 | originalHandler(e, isFatal); 34 | }, 500); 35 | } 36 | } 37 | } 38 | global.ErrorUtils.setGlobalHandler(errorHandler); 39 | } 40 | 41 | module.exports = { 42 | init, 43 | } 44 | --------------------------------------------------------------------------------