React Native Assignment– 10
Debugging, Profiling & Error Handling
Basic Questions
- Install and open React Native Debugger (standalone). Attach it to a running app and confirm it’s connected.
- Use React Native Debugger to inspect the component hierarchy and identify the top three mounted components on the current screen.
- In React Native Debugger, watch a component’s state and props in real time while pressing a button that updates state; capture a screenshot.
- Inspect AsyncStorage values during runtime via the debugger and read a stored auth token; then update it and verify the change in-app.
- Enable network inspect in React Native Debugger and verify a GET request’s URL, status code, and response time.
- Install Flipper, connect it to your app (Android emulator or iOS simulator), and verify the device appears in Flipper.
- Use Flipper’s Network plugin to capture an API call; expand the entry to view request headers and response payload.
- Add a Redux store to the app (or use an existing one) and install the Flipper redux-debugger plugin; verify that dispatches appear live.
- Trigger two different Redux actions and confirm their previous state → action → next state transitions in Flipper.
- 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
- Use Flipper’s Performance plugin (or React Native Performance Monitor) to profile a screen; list the slowest render and its time.
- Record memory usage before and after navigating through a list-heavy screen; note any persistent increase and potential leak suspect.
- 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.
- Implement an Error Boundary class with componentDidCatch(error, info) and wrap your main screen; crash a child component to confirm the fallback UI shows.
- Display a user-friendly fallback UI that includes a “Report Issue” button; ensure normal navigation still works.
- Set up a global JS error handler using ErrorUtils.setGlobalHandler (or the platform equivalent); intentionally throw and confirm the handler logs the error.
- Log unhandled promise rejections globally and capture stack traces; simulate a rejected fetch without catch.
- 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.
- Route users to an error reporting flow (screen with form or mailto link) when a fatal error occurs; include last action details.
- 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.
- Replace ad-hoc string logs with structured JSON logs (e.g., { level, event, context, ts }) and print two events.
- Add request/response structured logs around an API call (include latency and status); confirm correlation with Flipper Network entries.
- Capture and log AsyncStorage read/write failures with try/catch; simulate an error and verify it’s recorded.
- Add breadcrumbs (array in memory) that push the last 10 user actions; include them when showing the fallback UI.
- Integrate source maps for better stack traces in development; confirm a stack maps to original source file/line.
- Use React Native Debugger’s timeline (or Profiler) to measure a state update cascade; reduce the cascade and compare.
- Add a feature flag to toggle verbose logging at runtime; verify logs adjust without app reload.
- Create a custom network logger that redacts sensitive fields (e.g., Authorization) before printing.
- Create a reusable useErrorBoundary() hook that throws to the nearest boundary for async errors (e.g., in effects); verify fallback UI is triggered.
- 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
- Set up Sentry in the app (JS layer): configure the DSN, environment (dev|staging|prod), and release version; verify an event reaches Sentry.
- 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.
- Configure Sentry breadcrumbs for navigation and network; verify they show in an error event timeline.
- Add error severity mapping (info, warning, error, fatal) and send a custom event for each type; verify categorization in Sentry.
- Attach user context (id/email) and custom tags (buildNumber, featureFlag) to Sentry events; confirm they index correctly for search.
- Implement release health and distribution grouping in Sentry; verify session and crash-free metrics.
- Set up Sentry source map upload in your build pipeline; confirm stack traces are de-minified to original source lines.
- 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.
- 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.
- 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.