React Native Assignment– 10

Debugging, Profiling & Error Handling

Basic Questions

  1. Install and open React Native Debugger (standalone). Attach it to a running app and confirm it’s connected.
  2. Use React Native Debugger to inspect the component hierarchy and identify the top three mounted components on the current screen.
  3. In React Native Debugger, watch a component’s state and props in real time while pressing a button that updates state; capture a screenshot.
  4. Inspect AsyncStorage values during runtime via the debugger and read a stored auth token; then update it and verify the change in-app.
  5. Enable network inspect in React Native Debugger and verify a GET request’s URL, status code, and response time.
  6. Install Flipper, connect it to your app (Android emulator or iOS simulator), and verify the device appears in Flipper.
  7. Use Flipper’s Network plugin to capture an API call; expand the entry to view request headers and response payload.
  8. Add a Redux store to the app (or use an existing one) and install the Flipper redux-debugger plugin; verify that dispatches appear live.
  9. Trigger two different Redux actions and confirm their previous state → action → next state transitions in Flipper.
  10. Use basic console logging in your code: add console.info, console.warn, and console.error for distinct events; verify all three appear in your logs.

Intermediate Questions

  1. Use Flipper’s Performance plugin (or React Native Performance Monitor) to profile a screen; list the slowest render and its time.
  2. Record memory usage before and after navigating through a list-heavy screen; note any persistent increase and potential leak suspect.
  3. Add why-did-you-render (or a custom render counter) to detect unnecessary re-renders on a component; fix one cause and prove reduced renders.
  4. Implement an Error Boundary class with componentDidCatch(error, info) and wrap your main screen; crash a child component to confirm the fallback UI shows.
  5. Display a user-friendly fallback UI that includes a “Report Issue” button; ensure normal navigation still works.
  6. Set up a global JS error handler using ErrorUtils.setGlobalHandler (or the platform equivalent); intentionally throw and confirm the handler logs the error.
  7. Log unhandled promise rejections globally and capture stack traces; simulate a rejected fetch without catch.
  8. Differentiate JavaScript vs native errors by throwing one JS error and provoking a native error (e.g., invalid native module call); document detection differences in logs.
  9. Route users to an error reporting flow (screen with form or mailto link) when a fatal error occurs; include last action details.
  10. Create a simple log level utility that wraps console.* and filters logs by INFO|WARN|ERROR based on an env variable; verify only allowed levels print in release mode.
  11. Replace ad-hoc string logs with structured JSON logs (e.g., { level, event, context, ts }) and print two events.
  12. Add request/response structured logs around an API call (include latency and status); confirm correlation with Flipper Network entries.
  13. Capture and log AsyncStorage read/write failures with try/catch; simulate an error and verify it’s recorded.
  14. Add breadcrumbs (array in memory) that push the last 10 user actions; include them when showing the fallback UI.
  15. Integrate source maps for better stack traces in development; confirm a stack maps to original source file/line.
  16. Use React Native Debugger’s timeline (or Profiler) to measure a state update cascade; reduce the cascade and compare.
  17. Add a feature flag to toggle verbose logging at runtime; verify logs adjust without app reload.
  18. Create a custom network logger that redacts sensitive fields (e.g., Authorization) before printing.
  19. Create a reusable useErrorBoundary() hook that throws to the nearest boundary for async errors (e.g., in effects); verify fallback UI is triggered.
  20. Write a short debug checklist for your app (attach debugger, check network, inspect state, profile renders, test boundary, review logs) and store it in the repo.

Advanced Questions

  1. Set up Sentry in the app (JS layer): configure the DSN, environment (dev|staging|prod), and release version; verify an event reaches Sentry.
  2. Add Sentry React Native native integration (Android & iOS) so native crashes are captured; simulate a native crash and confirm it appears with device/context data.
  3. Configure Sentry breadcrumbs for navigation and network; verify they show in an error event timeline.
  4. Add error severity mapping (info, warning, error, fatal) and send a custom event for each type; verify categorization in Sentry.
  5. Attach user context (id/email) and custom tags (buildNumber, featureFlag) to Sentry events; confirm they index correctly for search.
  6. Implement release health and distribution grouping in Sentry; verify session and crash-free metrics.
  7. Set up Sentry source map upload in your build pipeline; confirm stack traces are de-minified to original source lines.
  8. Build a crash repro switch: a hidden settings toggle that triggers a JS error, a native crash, and a rejected promise; ensure each path is captured distinctly in Sentry and your local logs.
  9. Create a performance profiling session: Flipper Performance + JS profiler around a list render; implement at least two optimizations (memoized rows, getItemLayout) and show improved render time/FPS.
  10. Final Hands-on Project:
    • React Native Debugger: inspect tree, live state/props, AsyncStorage; network inspect
    • Flipper: network inspector, Redux plugin, performance plugin (render/memory)
    • Error handling: Error Boundary with custom fallback, global JS error handler, unhandled rejection capture, redirect to reporting
    • Logging: log levels, structured JSON logs, redaction of sensitive data, breadcrumbs
    • Sentry: DSN configured, native + JS crash capture, source maps, severity, user context/tags
    • Deliver a troubleshooting guide (README) with steps, screenshots, and before/after performance metrics.