ReferenceError: talk is not defined

C30935608bc34b1c854293de06c13c89?s=47 Hugo
September 06, 2019

ReferenceError: talk is not defined

Errar é humano. Mas o que fazer para evitar erros nos nossos apps React? Algumas boas práticas podem fazer toda a diferença para a experiência do usuário.

C30935608bc34b1c854293de06c13c89?s=128

Hugo

September 06, 2019
Tweet

Transcript

  1. ReferenceError talk is not defined

  2. @hugobessaa

  3. Exception

  4. function getPage(limit, page, data) { let firstIndex = (page -

    1) * limit; let lastIndex = firstIndex + limit; let pageData = data.slice(firstIndex, lastIndex); if (pageData.length === 0) { throw new Error(`Page ${page} does not exist`); } return pageData; }
  5. function getPage(limit, page, data) { let firstIndex = (page -

    1) * limit; let lastIndex = firstIndex + limit; let pageData = data.slice(firstIndex, lastIndex); if (pageData.length === 0) { throw new Error(`Page ${page} does not exist`); } return pageData; }
  6. None
  7. getPage()

  8. render() getData() getPage()

  9. render() getData() getPage()

  10. render() getData() getPage()

  11. render() getData() getPage()

  12. render() getData() getPage()

  13. render() getData() getPage()

  14. Unhandled Exception

  15. Vão terminar toda a call stack

  16. function getPage(limit, page, data) { let firstIndex = (page -

    1) * limit; let lastIndex = firstIndex + limit; let pageData = data.slice(firstIndex, lastIndex); if (pageData.length === 0) { throw new Error(`Page ${page} does not exist`); } return pageData; }
  17. function getPage(limit, page, data) { let firstIndex = (page -

    1) * limit; let lastIndex = firstIndex + limit; let pageData = data.slice(firstIndex, lastIndex); if (pageData.length === 0) { throw new Error(`Page ${page} does not exist`); } return pageData; }
  18. function getPage(limit, page, data) { let firstIndex = (page -

    1) * limit; let lastIndex = firstIndex + limit; let pageData = data.slice(firstIndex, lastIndex); if (pageData.length === 0) { throw new Error(`Page ${page} does not exist`); } return pageData; }
  19. function getPage(limit, page, data) { let firstIndex = (page -

    1) * limit; let lastIndex = firstIndex + limit; let pageData = data.slice(firstIndex, lastIndex); if (pageData.length === 0) { throw new Error(`Page ${page} does not exist`); } return pageData; }
  20. function getPage(limit, page, data) { let firstIndex = (page -

    1) * limit; let lastIndex = firstIndex + limit; let pageData = data.slice(firstIndex, lastIndex); if (pageData.length === 0) { throw new Error(`Page ${page} does not exist`); } return pageData; }
  21. function getPage(limit, page, data) { let firstIndex = (page -

    1) * limit; let lastIndex = firstIndex + limit; let pageData = data.slice(firstIndex, lastIndex); if (pageData.length === 0) { throw new Error(`Page ${page} does not exist`); } return pageData; }
  22. async function render(user) { let data = await getData(user); let

    pageData = getPage(10, 1, data); return renderPage(pageData); }
  23. <body> <div id="root"></div> <script src="./script.js"></script> </body>

  24. Unhandled Exception

  25. async function render(user) { let data = await getData(user); try

    { let pageData = getPage(10, 1, data); return renderPage(pageData); } catch (e) { console.error(e); return renderEmptyPage(); } }
  26. async function render(user) { let data = await getData(user); try

    { let pageData = getPage(10, 1, data); return renderPage(pageData); } catch (e) { console.error(e); return renderEmptyPage(); } }
  27. function getPage(limit, page, data) { let firstIndex = (page -

    1) * limit; let lastIndex = firstIndex + limit; let pageData = data.slice(firstIndex, lastIndex); if (pageData.length === 0) { throw new Error(`Page ${page} does not exist`); } return pageData; }
  28. async function render(user) { let data = await getData(user); try

    { let pageData = getPage(10, 1, data); return renderPage(pageData); } catch (e) { console.error(e); return renderEmptyPage(); } }
  29. async function render(user) { let data = await getData(user); try

    { let pageData = getPage(10, 1, data); return renderPage(pageData); } catch (e) { console.error(e); return renderEmptyPage(); } }
  30. async function render(user) { let data = await getData(user); try

    { let pageData = getPage(10, 1, data); return renderPage(pageData); } catch (e) { console.error(e); return renderEmptyPage(); } }
  31. async function render(user) { let data = await getData(user); try

    { let pageData = getPage(10, 1, data); return renderPage(pageData); } catch (e) { console.error(e); return renderEmptyPage(); } }
  32. <App> <Header /> <Body> <RocketDashboard data={monitoredRockets} layout='grid' /> </Body> </App>

  33. <App> <Header /> <Body> <RocketDashboard data={monitoredRockets} layout='grid' /> </Body> </App>

  34. <App> <Header /> <Body> try { <RocketDashboard data={monitoredRockets} layout='grid' />

    } catch (e) { <ErrorMessage /> } </Body> </App>
  35. <App> <Header /> <Body> <RocketDashboard data={monitoredRockets} layout='grid' /> </Body> </App>

    Declarativo
  36. Rockets Falcon 9 LEO 22,800 GTO 8,300 Saturn V LEO

    140,000 TLI 48,600 Soyuz-FG LEO 6,900 SSO 4,500 Space Shuttle LEO 27,500 Electron SSO 225 Falcon Heavy LEO 63,800 Search
  37. Rockets Falcon 9 LEO 22,800 GTO 8,300 Saturn V LEO

    140,000 TLI 48,600 Soyuz-FG LEO 6,900 SSO 4,500 Space Shuttle LEO 27,500 Electron SSO 225 Falcon Heavy LEO 63,800 Search
  38. Rockets Falcon 9 LEO 22,800 GTO 8,300 Saturn V LEO

    140,000 TLI 48,600 Soyuz-FG LEO 6,900 SSO 4,500 Space Shuttle LEO 27,500 Electron SSO 225 Falcon Heavy LEO 63,800 Search
  39. Rockets Falcon 9 LEO 22,800 GTO 8,300 Saturn V LEO

    140,000 TLI 48,600 Soyuz-FG LEO 6,900 SSO 4,500 Space Shuttle LEO 27,500 Electron SSO 225 Falcon Heavy LEO 63,800 Search
  40. Rockets Falcon 9 LEO 22,800 GTO 8,300 Saturn V LEO

    140,000 TLI 48,600 Soyuz-FG LEO 6,900 SSO 4,500 Space Shuttle LEO 27,500 Electron SSO 225 Falcon Heavy LEO 63,800 Search
  41. Rockets Falcon 9 LEO 22,800 GTO 8,300 Saturn V LEO

    140,000 TLI 48,600 Soyuz-FG LEO 6,900 SSO 4,500 Space Shuttle LEO 27,500 Electron SSO 225 Falcon Heavy LEO 63,800 Search
  42. Rockets Falcon 9 LEO 22,800 GTO 8,300 Saturn V LEO

    140,000 TLI 48,600 Soyuz-FG LEO 6,900 SSO 4,500 Space Shuttle LEO 27,500 Electron SSO 225 Falcon Heavy LEO 63,800 Search
  43. Rockets Falcon 9 LEO 22,800 GTO 8,300 Saturn V LEO

    140,000 TLI 48,600 Soyuz-FG LEO 6,900 SSO 4,500 Space Shuttle LEO 27,500 Electron SSO 225 Falcon Heavy LEO 63,800 Search
  44. Rockets Falcon 9 LEO 22,800 GTO 8,300 Saturn V LEO

    140,000 TLI 48,600 Soyuz-FG LEO 6,900 SSO 4,500 Space Shuttle LEO 27,500 Electron SSO 225 Falcon Heavy LEO 63,800 Search
  45. None
  46. None
  47. None
  48. Rockets Falcon 9 LEO 22,800 GTO 8,300 Saturn V LEO

    140,000 TLI 48,600 Soyuz-FG LEO 6,900 SSO 4,500 Space Shuttle LEO 27,500 Electron SSO 225 Falcon Heavy LEO 63,800 Search
  49. None
  50. None
  51. Rockets Falcon 9 LEO 22,800 GTO 8,300 Saturn V LEO

    140,000 TLI 48,600 Soyuz-FG LEO 6,900 SSO 4,500 Space Shuttle LEO 27,500 Electron SSO 225 Falcon Heavy LEO 63,800 Search
  52. Rockets Falcon 9 LEO 22,800 GTO 8,300 Saturn V LEO

    140,000 TLI 48,600 Space Shuttle LEO 27,500 Electron SSO 225 Falcon Heavy LEO 63,800 Search Unavailable
  53. Rockets Falcon 9 LEO 22,800 GTO 8,300 Saturn V LEO

    140,000 TLI 48,600 Soyuz-FG LEO 6,900 SSO 4,500 Space Shuttle LEO 27,500 Electron SSO 225 Falcon Heavy LEO 63,800 Search
  54. Rockets Falcon 9 LEO 22,800 GTO 8,300 Saturn V LEO

    140,000 TLI 48,600 Soyuz-FG LEO 6,900 SSO 4,500 Space Shuttle LEO 27,500 Electron SSO 225 Falcon Heavy LEO 63,800
  55. class RocketDetails extends Component { render() { let { title,

    info } = this.props; return ( <article> <h2>{title}</h2> <dl> <dt>{info[0].label}</dt> <dd>{info[0].value}</dd> <dt>{info[1].label}</dt> <dd>{info[1].value}</dd> </dl> </article> ); } }
  56. class RocketDetails extends Component { static getDerivedStateFromError(error) { return {

    error: true }; } render() { let { title, info } = this.props; return ( <article> <h2>{title}</h2> <dl> <dt>{info[0].label}</dt> <dd>{info[0].value}</dd> <dt>{info[1].label}</dt> <dd>{info[1].value}</dd> </dl> </article>
  57. if (this.state.error) { return <span>Unavailable</span> }

  58. Rockets Falcon 9 LEO 22,800 GTO 8,300 Saturn V LEO

    140,000 TLI 48,600 Space Shuttle LEO 27,500 Electron SSO 225 Falcon Heavy LEO 63,800 Search Unavailable
  59. class Search extends Component { state = { value: ''

    }; render() { return ( <form onSubmit={this.handleSubmit}> <input name='search' value={this.state.value} onChange={ (e) => this.setState({ value: e.target.value }) } /> </form> );
  60. class Search extends Component { state = { value: ''

    }; render() { return ( <form onSubmit={this.handleSubmit}> <input name='search' value={this.state.value} onChange={ (e) => this.setState({ value: e.target.value }) } /> </form> );
  61. class Search extends Component { state = { value: ''

    }; render() { return ( <form onSubmit={this.handleSubmit}> <input name='search' value={this.state.value} onChange={ (e) => this.setState({ value: e.target.value }) } /> </form> );
  62. class Search extends Component { state = { value: ''

    }; render() { return ( <form onSubmit={this.handleSubmit}> <input name='search' value={this.state.value} onChange={ (e) => this.setState({ value: e.target.value }) } /> </form> );
  63. (e) => this.setState({ value: e.target.value }) } /> </form> );

    } handleSubmit = (e) => { e.preventDefault(); performSearch({ query: this.state.value }); }; }
  64. (e) => this.setState({ value: e.target.value }) } /> </form> );

    } handleSubmit = (e) => { e.preventDefault(); performSearch({ query: this.state.value }); }; }
  65. (e) => this.setState({ value: e.target.value }) } /> </form> );

    } handleSubmit = (e) => { e.preventDefault(); performSearch({ query: this.state.value }); }; }
  66. Exceções em event handlers precisam de try…catch

  67. render()

  68. render() onChange()

  69. handleSubmit = (e) => { e.preventDefault(); try { performSearch({ query:

    this.state.value }); } catch (e) { this.setState({ error: true }); } };
  70. Server-side rendering

  71. None
  72. None
  73. None
  74. try { return renderToString(<App />); } catch (e) { console.error(e);

    return undefined }
  75. É assim que fazemos em telnyx.com

  76. None
  77. Como monitorar?

  78. None
  79. Sentry.init({ dsn: 'https://<key>@sentry.io/<project>' })

  80. None
  81. None
  82. class RocketDetails extends Component { static getDerivedStateFromError(error) { return {

    error: true }; } render() { let { title, info } = this.props; return ( <article> <h2>{title}</h2> <dl> <dt>{info[0].label}</dt> <dd>{info[0].value}</dd> <dt>{info[1].label}</dt> <dd>{info[1].value}</dd> </dl> </article>
  83. class RocketDetails extends Component { static getDerivedStateFromError(error) { return {

    error: true }; } componentDidCatch(error, info) { console.error(error, info); Sentry.captureException(err); } render() { let { title, info } = this.props; return ( <article> <h2>{title}</h2> <dl> <dt>{info[0].label}</dt>
  84. None
  85. Unhandled Exception

  86. Uma hora vai acontecer

  87. Nós podemos diminuir o impacto dos erros

  88. Rockets Falcon 9 LEO 22,800 GTO 8,300 Saturn V LEO

    140,000 TLI 48,600 Space Shuttle LEO 27,500 Electron SSO 225 Falcon Heavy LEO 63,800 Search Unavailable
  89. None
  90. static getDerivedStateFromError(error) { return { error: true }; } componentDidCatch(error,

    info) { console.error(error, info); Sentry.captureException(err); }
  91. Não deixe seu usuário ver uma tela branca

  92. None
  93. None
  94. telnyx.com/careers

  95. @hugobessaa