简体   繁体   中英

Error handling API fetch request with React

I'm using React, and just wanted some advice on error handling.

I have my fetch request in an async function, this function is in another folder and is being imported in my App.js file. Im doing this because I want to try out testing with mock service worker, and have read its easier with the requests in a separate file.

From looking at my code below, is this best practice for error handling? Is there a better way thats more concise?

Here is my fetch async function, at the moment i've purposely gave the wrong env variable name so it will give me a 401 unauthorised error.

require('dotenv').config()

export const collect = async () => {
    const key = process.env.REACT_APP_API_KE
    try{
      const res = await fetch(`http://api.openweathermap.org/data/2.5/weather?q=london&appid=${key}`)
      if(res.status !== 200){
          throw new Error(res.status)
      }
        const data = await res.json()
        return data
      } catch (error){
        let err = {
          error: true,
          status: error.message,
        }
        return err
      }
}

This is being called in my App.js file (not rendering much at the moment)

import { useState } from 'react'
import { collect } from './utilities/collect'
require('dotenv').config()

function App() {
  const [data, setData] = useState("")
  const [error, setError] = useState({ error: false, status: "" })
  const handleFetch = async () => {
      let newData = await collect()
      if(newData.error){
        setError({ error: newData.error, status: newData.status })
      }else {
        setData(newData)
      }
  }
  return (
    <div className="App">
      <h1>weather</h1>
      <button onClick={handleFetch}>fetch</button>
    </div>
  );
}

export default App;

Any help or advise would be great.

When writing an abstraction around Promises or async and await one should make sure it is used appropriately, that is a good Promse must allow it consumer to use it then and catch method or should allow it consumer use try and catch to consume it and provide appropriate information on Errors

From Your code, The abstraction doesnt gives back an appropriate response and doesnt follow the standard behavior of a promise it always resolve and never reject and though the code works its implementation of the collect is different from a standard Promise and wont be nice for a standard code base, for example a good abstraction will provide error information returned from the third party api

Appropriate way to amend code

The third party api returns this response

{
 "cod":401, 
 "message": "Invalid API key. Please see http://openweathermap.org/faq#error401 for more info."} 

This should be your implementation

// Your fetch functon abstraction modified
require('dotenv').config()
const collect = async () => {
    const key = process.env.REACT_APP_API_KE;
      const res = await fetch(
        `http://api.openweathermap.org/data/2.5/weather?q=london&appid=${key}`,
      );
      if (res.status !== 200) {

        const error = await res.json();
        throw {message: error.message,status:error.cod};
      }
      const data = await res.json();
      return data;
  };
  

Your app component should now be like this

import { useState } from 'react'
import { collect } from './utilities/collect'
require('dotenv').config()

function App() {
  const [data, setData] = useState("")
  const [error, setError] = useState({ error: false, status: "" })
  const handleFetch = async () => {
      try {
            let newData = await collect()
            setData(newData)
      } catch(e){
          setError({ error: e.message, status: e.status })
      }
  }
  return (
    <div className="App">
      <h1>weather</h1>
      <button onClick={handleFetch}>fetch</button>
    </div>
  );
}

export default App;

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM