reactjsnext.jsstackdriver

Next.js - Stack Driver error reporting - errors are not logged


I tried to log errors from Next.js app into Stack Driver.

With this library: https://github.com/GoogleCloudPlatform/stackdriver-errors-js

App.tsx

useEffect(() => {
   TagManager.initialize({
     gtmId: process.env.NEXT_PUBLIC_GTM_ID as string,
   })

   if (process.env.NODE_ENV !== 'development') {
     const errorHandler = new StackdriverErrorReporter()
     errorHandler.start({
       key: process.env.NEXT_PUBLIC_API_KEY || '',
       projectId: process.env.NEXT_PUBLIC_PROJECT_ID || '',
       service: 'service_id',
       version: '2',
     })

     window.onerror = function (_msg, _file, _line, _col, error) {
       // callback is called with an Array[StackFrame]
       if (error) {
         errorHandler.report(error)
       }
     }
  }
}, [])

But no errors are logged in stack-driver. Has anyone faced this issue before? I'll post there my next journey in this situation.

Thanks!


Solution

  • I resolved this by using custom ErrorBoundary and wrapped whole _app.tsx:

    //cc @John Handley

    import React, { Component, ErrorInfo, ReactNode } from 'react'
    import StackdriverErrorReporter from 'stackdriver-errors-js'
    
    interface Props {
      children?: ReactNode
    }
    
    interface State {
      hasError: boolean
    }
    
    class AppErrorBoundary extends Component<Props, State> {
      public state: State = {
        hasError: false,
      }
    
      public static getDerivedStateFromError(_: Error): State {
        // Update state so the next render will show the fallback UI.
        return { hasError: true }
      }
    
      public componentDidCatch(error: Error, errorInfo: ErrorInfo) {
        const errorHandler = new StackdriverErrorReporter()
        errorHandler.start({
          key: process.env.NEXT_PUBLIC_API_KEY || '',
          projectId: process.env.NEXT_PUBLIC_PROJECT_ID || '',
          service: '',
          version: '2',
        })
    
        errorHandler.report(error)
        console.error('Uncaught error:', error, errorInfo)
      }
    
      public render() {
        if (this.state.hasError) {
          return <h1>Sorry.. there was an error</h1>
        }
    
        return this.props.children
      }
    }
    
    export default AppErrorBoundary