最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - componentDidCatch is not triggered even when I throw an error in my constructor - Stack Overflow

programmeradmin1浏览0评论

I can't seem to trigger ponentDidCatch in my code, even though I am purposefully throwing an error inside of my constructor function, so I know I'm not throwing the error on an event handler. My concern is that I did not successfully update my project to React 16, which is why ponentDidCatch is not working. Could it be that I have not successfuly upgraded to React 16, or am I misusing Error Boundaries?

Here are posts I have already reviewed and used to get this far:

  1. Error handling in React best practices

  2. React 16 Error Boundary ponent (using ponentDidCatch) shows uncaught error

  3. Introducing Error Boundaries

App.js

import React, { Component } from 'react'
import axios from 'axios'

import ErrorBoundary from './ponents/ErrorBoundary'
import Home from './ponents/Home'
import Login from './ponents/Login'

class App extends Component {
  constructor (props) {
    super(props)

    this.state = {
      loggedIn: false,
      hasError: false
    }
    // This is where I am throwing my Error
    throw new Error('this should be caught')
  }

  ponentWillMount () {
    axios.get(this.url, {
      withCredentials: true
    })
    .then((response) => {
      if (response.status === 200) { 
        if (response.data.isAuthenticated) {
          this.setState({ loggedIn: true })
        } else if (!response.data.isAuthenticated) {
          this.setState({ loggedIn: false })
        } 
      }
    })
    .catch((error) => {
      this.setState(state => ({ ...state, hasErrors: true }))
      throw new Error("We couldn't get a response from the server.")
    })
  }

  render () {
    if (!this.state.loggedIn && !this.state.hasErrors) {
      return (
        <div className='login-container'>
          // I am setting an Error Boundary
          <ErrorBoundary>
            <Login url={this.url} />
          </ErrorBoundary>
        </div>
      )
    } else if (this.state.loggedIn && !this.state.hasErrors) {
      return (
        <div>
          // I am setting an Error Boundary
          <ErrorBoundary>
            <Home url={this.url} />
          </ErrorBoundary>
        </div>
      )
    } else { 
      return <h1>Something has gone wrong.</h1>
    }
  }
}

export default App

ErrorBoundary.js

import React, { Component } from 'react'

class ErrorBoundary extends Component {
  constructor (props) {
    super(props)
    this.state = { hasError: false }
  }

  ponentDidCatch (error, info) {
    this.setState(state => ({ ...state, hasError: true }))
  }

  render () {
    if (this.state.hasError) {
      return <h1>Something went wrong.</h1>
    }
    return this.props.children
  }
}

export default ErrorBoundary

package.json

{
  "name": "spotify-analyzer-frontend",
  "version": "0.1.0",
  "private": true,
  "dependencies": {
    "babel-eslint": "^7.2.3",
    "dotenv": "^4.0.0",
    "flexbox-react": "^4.4.0",
    "highcharts": "^5.0.14",
    "material-ui-search-bar": "^0.4.0",
    "prop-types": "^15.6.0",
    "react": "^16.1.1",
    "react-dom": "^16.1.1",
    "react-flexbox-grid": "^2.0.0",
    "react-highcharts": "^12.0.0",
    "react-jss": "^8.0.0",
    "react-scripts": "1.0.11",
    "react-tap-event-plugin": "^2.0.1",
    "standard": "^10.0.3"
  },
  "scripts": {
    "start": "react-scripts start",
    "build": "react-scripts build",
    "test": "react-scripts test --env=jsdom",
    "eject": "react-scripts eject"
  },
  "proxy": "",
  "devDependencies": {
    "axios": "^0.16.2",
    "babel-eslint": "^8.0.2",
    "babel-jest": "^21.0.0",
    "css.escape": "^1.5.1",
    "enzyme": "^3.2.0",
    "enzyme-adapter-react-16": "^1.1.0",
    "eslint": "^4.5.0",
    "eslint-plugin-react": "^7.3.0",
    "jest": "^21.0.1",
    "material-ui": "^0.19.1",
    "regenerator-runtime": "^0.11.0",
    "standard": "^10.0.3"
  },
  "standard": {
    "ignore": [
      "__tests__/**.test.js"
    ]
  }
}

node_modules/react/package.json

    {
  "_args": [
    [
      {
        "raw": "react@next",
        "scope": null,
        "escapedName": "react",
        "name": "react",
        "rawSpec": "next",
        "spec": "next",
        "type": "tag"
      },
      "/Users/maecapozzi/Desktop/Codes/spotify-analyzer-frontend"
    ]
  ],
  "_from": "react@next",
  "_id": "[email protected]",
  "_inCache": true,
  "_location": "/react",
  "_nodeVersion": "8.6.0",
  "_npmOperationalInternal": {
    "host": "s3://npm-registry-packages",
    "tmp": "tmp/react-16.1.1.tgz_1510589592482_0.18714527692645788"
  },
  "_npmUser": {
    "name": "gaearon",
    "email": "[email protected]"
  },
  "_npmVersion": "5.5.1",
  "_phantomChildren": {},
  "_requested": {
    "raw": "react@next",
    "scope": null,
    "escapedName": "react",
    "name": "react",
    "rawSpec": "next",
    "spec": "next",
    "type": "tag"
  },
  "_requiredBy": [
    "#USER",
    "/"
  ],
  "_resolved": ".1.1.tgz",
  "_shasum": "d5c4ef795507e3012282dd51261ff9c0e824fe1f",
  "_shrinkwrap": null,
  "_spec": "react@next",
  "_where": "/Users/maecapozzi/Desktop/Codes/spotify-analyzer-frontend",
  "browserify": {
    "transform": [
      "loose-envify"
    ]
  },
  "bugs": {
    "url": ""
  },
  "dependencies": {
    "fbjs": "^0.8.16",
    "loose-envify": "^1.1.0",
    "object-assign": "^4.1.1",
    "prop-types": "^15.6.0"
  },
  "description": "React is a JavaScript library for building user interfaces.",
  "devDependencies": {},
  "directories": {},
  "dist": {
    "integrity": "sha512-FQfiFfk2z2Fk87OngNJHT05KyC9DOVn8LPeB7ZX+9u5+yU1JK6o5ozRlU3PeOMr0IFkWNvgn9jU8/IhRxR1F0g==",
    "shasum": "d5c4ef795507e3012282dd51261ff9c0e824fe1f",
    "tarball": ".1.1.tgz"
  },
  "engines": {
    "node": ">=0.10.0"
  },
  "files": [
    "LICENSE",
    "README.md",
    "index.js",
    "cjs/",
    "umd/"
  ],
  "homepage": "/",
  "keywords": [
    "react"
  ],
  "license": "MIT",
  "main": "index.js",
  "maintainers": [
    {
      "name": "acdlite",
      "email": "[email protected]"
    },
    {
      "name": "sophiebits",
      "email": "[email protected]"
    },
    {
      "name": "flarnie",
      "email": "[email protected]"
    },
    {
      "name": "gaearon",
      "email": "[email protected]"
    },
    {
      "name": "trueadm",
      "email": "[email protected]"
    },
    {
      "name": "brianvaughn",
      "email": "[email protected]"
    },
    {
      "name": "fb",
      "email": "[email protected]"
    }
  ],
  "name": "react",
  "optionalDependencies": {},
  "readme": "ERROR: No README data found!",
  "repository": {
    "type": "git",
    "url": "git+.git"
  },
  "version": "16.1.1"
}

I can't seem to trigger ponentDidCatch in my code, even though I am purposefully throwing an error inside of my constructor function, so I know I'm not throwing the error on an event handler. My concern is that I did not successfully update my project to React 16, which is why ponentDidCatch is not working. Could it be that I have not successfuly upgraded to React 16, or am I misusing Error Boundaries?

Here are posts I have already reviewed and used to get this far:

  1. Error handling in React best practices

  2. React 16 Error Boundary ponent (using ponentDidCatch) shows uncaught error

  3. Introducing Error Boundaries

App.js

import React, { Component } from 'react'
import axios from 'axios'

import ErrorBoundary from './ponents/ErrorBoundary'
import Home from './ponents/Home'
import Login from './ponents/Login'

class App extends Component {
  constructor (props) {
    super(props)

    this.state = {
      loggedIn: false,
      hasError: false
    }
    // This is where I am throwing my Error
    throw new Error('this should be caught')
  }

  ponentWillMount () {
    axios.get(this.url, {
      withCredentials: true
    })
    .then((response) => {
      if (response.status === 200) { 
        if (response.data.isAuthenticated) {
          this.setState({ loggedIn: true })
        } else if (!response.data.isAuthenticated) {
          this.setState({ loggedIn: false })
        } 
      }
    })
    .catch((error) => {
      this.setState(state => ({ ...state, hasErrors: true }))
      throw new Error("We couldn't get a response from the server.")
    })
  }

  render () {
    if (!this.state.loggedIn && !this.state.hasErrors) {
      return (
        <div className='login-container'>
          // I am setting an Error Boundary
          <ErrorBoundary>
            <Login url={this.url} />
          </ErrorBoundary>
        </div>
      )
    } else if (this.state.loggedIn && !this.state.hasErrors) {
      return (
        <div>
          // I am setting an Error Boundary
          <ErrorBoundary>
            <Home url={this.url} />
          </ErrorBoundary>
        </div>
      )
    } else { 
      return <h1>Something has gone wrong.</h1>
    }
  }
}

export default App

ErrorBoundary.js

import React, { Component } from 'react'

class ErrorBoundary extends Component {
  constructor (props) {
    super(props)
    this.state = { hasError: false }
  }

  ponentDidCatch (error, info) {
    this.setState(state => ({ ...state, hasError: true }))
  }

  render () {
    if (this.state.hasError) {
      return <h1>Something went wrong.</h1>
    }
    return this.props.children
  }
}

export default ErrorBoundary

package.json

{
  "name": "spotify-analyzer-frontend",
  "version": "0.1.0",
  "private": true,
  "dependencies": {
    "babel-eslint": "^7.2.3",
    "dotenv": "^4.0.0",
    "flexbox-react": "^4.4.0",
    "highcharts": "^5.0.14",
    "material-ui-search-bar": "^0.4.0",
    "prop-types": "^15.6.0",
    "react": "^16.1.1",
    "react-dom": "^16.1.1",
    "react-flexbox-grid": "^2.0.0",
    "react-highcharts": "^12.0.0",
    "react-jss": "^8.0.0",
    "react-scripts": "1.0.11",
    "react-tap-event-plugin": "^2.0.1",
    "standard": "^10.0.3"
  },
  "scripts": {
    "start": "react-scripts start",
    "build": "react-scripts build",
    "test": "react-scripts test --env=jsdom",
    "eject": "react-scripts eject"
  },
  "proxy": "https://spotify-viz-api.herokuapp.",
  "devDependencies": {
    "axios": "^0.16.2",
    "babel-eslint": "^8.0.2",
    "babel-jest": "^21.0.0",
    "css.escape": "^1.5.1",
    "enzyme": "^3.2.0",
    "enzyme-adapter-react-16": "^1.1.0",
    "eslint": "^4.5.0",
    "eslint-plugin-react": "^7.3.0",
    "jest": "^21.0.1",
    "material-ui": "^0.19.1",
    "regenerator-runtime": "^0.11.0",
    "standard": "^10.0.3"
  },
  "standard": {
    "ignore": [
      "__tests__/**.test.js"
    ]
  }
}

node_modules/react/package.json

    {
  "_args": [
    [
      {
        "raw": "react@next",
        "scope": null,
        "escapedName": "react",
        "name": "react",
        "rawSpec": "next",
        "spec": "next",
        "type": "tag"
      },
      "/Users/maecapozzi/Desktop/Codes/spotify-analyzer-frontend"
    ]
  ],
  "_from": "react@next",
  "_id": "[email protected]",
  "_inCache": true,
  "_location": "/react",
  "_nodeVersion": "8.6.0",
  "_npmOperationalInternal": {
    "host": "s3://npm-registry-packages",
    "tmp": "tmp/react-16.1.1.tgz_1510589592482_0.18714527692645788"
  },
  "_npmUser": {
    "name": "gaearon",
    "email": "[email protected]"
  },
  "_npmVersion": "5.5.1",
  "_phantomChildren": {},
  "_requested": {
    "raw": "react@next",
    "scope": null,
    "escapedName": "react",
    "name": "react",
    "rawSpec": "next",
    "spec": "next",
    "type": "tag"
  },
  "_requiredBy": [
    "#USER",
    "/"
  ],
  "_resolved": "https://registry.npmjs/react/-/react-16.1.1.tgz",
  "_shasum": "d5c4ef795507e3012282dd51261ff9c0e824fe1f",
  "_shrinkwrap": null,
  "_spec": "react@next",
  "_where": "/Users/maecapozzi/Desktop/Codes/spotify-analyzer-frontend",
  "browserify": {
    "transform": [
      "loose-envify"
    ]
  },
  "bugs": {
    "url": "https://github./facebook/react/issues"
  },
  "dependencies": {
    "fbjs": "^0.8.16",
    "loose-envify": "^1.1.0",
    "object-assign": "^4.1.1",
    "prop-types": "^15.6.0"
  },
  "description": "React is a JavaScript library for building user interfaces.",
  "devDependencies": {},
  "directories": {},
  "dist": {
    "integrity": "sha512-FQfiFfk2z2Fk87OngNJHT05KyC9DOVn8LPeB7ZX+9u5+yU1JK6o5ozRlU3PeOMr0IFkWNvgn9jU8/IhRxR1F0g==",
    "shasum": "d5c4ef795507e3012282dd51261ff9c0e824fe1f",
    "tarball": "https://registry.npmjs/react/-/react-16.1.1.tgz"
  },
  "engines": {
    "node": ">=0.10.0"
  },
  "files": [
    "LICENSE",
    "README.md",
    "index.js",
    "cjs/",
    "umd/"
  ],
  "homepage": "https://reactjs/",
  "keywords": [
    "react"
  ],
  "license": "MIT",
  "main": "index.js",
  "maintainers": [
    {
      "name": "acdlite",
      "email": "[email protected]"
    },
    {
      "name": "sophiebits",
      "email": "[email protected]"
    },
    {
      "name": "flarnie",
      "email": "[email protected]"
    },
    {
      "name": "gaearon",
      "email": "[email protected]"
    },
    {
      "name": "trueadm",
      "email": "[email protected]"
    },
    {
      "name": "brianvaughn",
      "email": "[email protected]"
    },
    {
      "name": "fb",
      "email": "[email protected]"
    }
  ],
  "name": "react",
  "optionalDependencies": {},
  "readme": "ERROR: No README data found!",
  "repository": {
    "type": "git",
    "url": "git+https://github./facebook/react.git"
  },
  "version": "16.1.1"
}
Share Improve this question edited Nov 25, 2017 at 19:29 maecapozzi asked Nov 25, 2017 at 19:21 maecapozzimaecapozzi 2401 gold badge4 silver badges10 bronze badges 3
  • It would be a good idea to confirm what version of React you have installed. Check the package-lock.json file in your project and search for "react". Or check directly in the node_modules/react folder and check the package.json of react. – Sidney Commented Nov 25, 2017 at 19:26
  • Hi @Sidney, I've added my node_modules/react/package.json file, if you wouldn't mind taking a look. It does seem to say I have [email protected]. – maecapozzi Commented Nov 25, 2017 at 19:30
  • You can test whether you've successfully upgraded to 16.x by returning a simple string from render, which was not supported until 16 gist.github./ahmedtehseen/… – Noel Commented Nov 25, 2017 at 19:40
Add a ment  | 

1 Answer 1

Reset to default 7

So from your code it looks like you're throwing the error in the parent.

Error boundaries are React ponents that catch JavaScript errors anywhere in their child ponent tree, log those errors, and display a fallback UI

Error boundaries catch errors in their child ponent tree.

So you need to have errors in your <Home> or <Login> ponents.

发布评论

评论列表(0)

  1. 暂无评论