Skip to content

Instantly share code, notes, and snippets.

@thinkgarden
Created July 23, 2018 07:59
Show Gist options
  • Save thinkgarden/e45d88773d1aa60cae342ddfca532e57 to your computer and use it in GitHub Desktop.
Save thinkgarden/e45d88773d1aa60cae342ddfca532e57 to your computer and use it in GitHub Desktop.
[react-native]

全局错误处理

/* eslint-disable */
import { setGlobalHandler } from 'ErrorUtils';
/* eslint-enable */


setGlobalHandler((error) => console.warn(error)); // eslint-disable-line

Navigation


const AppNavigator = StackNavigator(routes, {
  headerMode: 'none'
});

const defaultGetStateForAction = AppNavigator.router.getStateForAction;

AppNavigator.router.getStateForAction = (action, state) => {
  if (action.type && action.type.startsWith('Nav')) {
    // console.log(action);
    // 所有的导航事件都会走这里,可以定制一些东西,
    // action 是跳转动作,state是当前StackNavigator的状态
    const routeName = action && action.routeName;
    const globalState = store && store.getState();
    const profile = globalState ? globalState.user.profile : {};
    const features = profile.features || [];
    if (!isPrivileged(routeName, features)) {
      setTimeout(() => {
        dispatchErrorMessage('没有权限访问此页面');
      }, 0);
      return state;
    }
  }
  return defaultGetStateForAction(action, state);
};


class AppNavigation extends Component {
  state = {
    appState: AppState.currentState
  }
  componentDidMount() {
    if (Platform.OS === 'ios') {
      JAnalyticsModule.setup({ appKey: 'xxxxxxxxxxxxxxx' });
    }
    if (Platform.OS !== 'ios') {
      RNSegmentIO.setup('xxxxxxxxxxxxxxxxxxx');
    }
    BackHandler.addEventListener('hardwareBackPress', () => {
      if (this.props.navigationState.index === 0 || this.props.navigationState.routes[1].routeName === 'Initial') {
        Alert.alert(
          '确认要退出么?',
          '',
          [
            { text: '暂时不', onPress: () => { }, style: 'cancel' },
            { text: '退出', onPress: () => BackHandler.exitApp() },
          ]
        );
      } else {
        this.props.dispatch(NavigationActions.back(null));
      }
      return true;
    });
    AppState.addEventListener('change', this._handleAppStateChange);
  }

  _handleAppStateChange = (nextAppState) => {
    if (this.state.appState.match(/inactive|background/) && nextAppState === 'active') {
      if (Platform.OS === 'ios') {
        JPushModule.setBadge(0, () => { });
      }
    }
    this.setState({ appState: nextAppState });
  }
  render() {
    const { dispatch, navigationState } = this.props;
    return (
      <AppNavigator
        navigation={
          addNavigationHelpers({
            dispatch,
            state: navigationState,
          })
        }
      />
    );
  }
}

localstore

import { AsyncStorage } from 'react-native';
import Storage from 'react-native-storage';

export default new Storage({
  storageBackend: AsyncStorage,
  defaultExpires: 1000 * 3600 * 24 * 30
});


export class FakeApi {
  // the url should be added the id, getting the specific value
  static async get(url) {
    try {
      const data = await storage.load({
        key: url
      });
      return data || {};
    } catch (error) {
      return {};
    }
  }

  static async put(url, body) {
    storage.save({
      key: url,
      data: body
    });
  }

}

fetch


export const errorInterceptor = new Interceptor({
  fetchError: {
    id: 1,
    requestError(error) {
      // Alert.alert('请求出错', '请求地址或网络错误');
      dispatchErrorMessage('请求失败,当前网络异常请稍候再试');
      // loadFinished();
      return Promise.reject(error);
    },
    error(res) {
      // throw new RemoteAPIError(res.url, res.status);
      // 在生产环境不显示错误的 URL

      const url = ENV === 'prod' ? '' : res.url;
      const errorMessage = ENV === 'prod' ? `服务器未知错误(${res.status}),请稍后尝试` : `url: ${url}, status: ${res.status}`;
      if (res.status >= 500) {
        return Promise.reject(res.message || errorMessage);
      }
      if (res.status === 401) {
        token.clear();
        token.autoLogin = false;
        const globalState = store && store.getState();
        const routes = globalState.nav.routes;
        const currentPage = routes[routes.length - 1].routeName;
        if (currentPage && currentPage !== 'Initial') {
          store.dispatch(LOGOUT.request());
          dispatchErrorMessage('Token 过期,请重新登录 APP');
        }
        return Promise.reject(res.message);
      }
      if (res.text) {
        res.json().then((data) => {
          if (data && data.message) {
            dispatchErrorMessage(data.message);
            return Promise.reject(new RemoteAPIError(url, res.status));
          }
          dispatchErrorMessage(errorMessage + data);
          return Promise.reject(new RemoteAPIError(url, res.status));
        }).catch(err => {
          // console.log('promise reject err');
        });
      } else {
        dispatchErrorMessage(errorMessage);
        return Promise.reject(new RemoteAPIError(url, res.status));
      }
    }
  },
  codeError: {
    id: 2,
    success(data) {
      if (data.code === -2 || data.code === 401) {
        token.clear();
        token.autoLogin = false;
        store.dispatch(LOGOUT.request());
        dispatchErrorMessage('Token 过期,请重新登录 APP');
        return Promise.reject(data.message);
      }

      if (data.code !== 0) {
        dispatchErrorMessage(data.message);
        return Promise.reject(data.message);
      }

      return Promise.resolve(data.data);
    }
  }
});



import { tokenInterceptor } from './token';
import { errorInterceptor } from './error';
import { timeoutInterceptor } from './timeout';
import { netInfoInterceptor } from './netInfo';

export const interceptors = tokenInterceptor
  .merge(netInfoInterceptor)
  .merge(errorInterceptor)
  .merge(timeoutInterceptor);



import { FetchClient } from 'intercept-fetch';
import { interceptors } from './interceptors';
import { config } from './config';
import './fetch';

const fetchClient = new FetchClient();
fetchClient.timeout = config.timeout;
fetchClient.setInterceptors(interceptors);

export default fetchClient;
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment