Let’s build a full stack UK weather app using Node + React: part 2 — error handling
Tags: react, node
Published: 2020-08-10 13:23:03

Original post on Medium see [here](https://medium.com/@duxiaohan_34311/lets-build-a-full-stack-uk-weather-app-using-node-react-part-2-error-handling-96323ca8e3c5), code example in this article can be found in [my Github Page](https://github.com/xiaohan-du/code-playground/tree/master/full-stack-weather-app).

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/eadmrxp8a87d3wlalfcb.png)

In [Part 1](https://dev.to/xiaohan_du/let-s-build-a-full-stack-uk-weather-app-using-node-react-part-1-basic-setup-4n1) we scaffolded a basic set up for our UK weather app and successfully fetched and displayed the weather data from Openweathermap API. An important point in part 1 was how user input data was stored in React state and sent to Node. You may have noticed that some errors happened when non-standard UK postcode was entered, thus in part 2 I’m going to show you my thoughts of handling these errors.

# The error
Let’s take a look at what happens if entering a random postcode in the input field: aa123aa

![Error without handling](https://dev-to-uploads.s3.amazonaws.com/i/ulv1u605ybma2gn92rch.png)

The error is pretty much self-explanatory: `response.result = undefined`. `Console.log(response)` and we can see:

![response](https://dev-to-uploads.s3.amazonaws.com/i/syr24q60obyjztboe1vm.png)

Openweathermap API returned a 404 error when a false postcode was entered.

# How to handle the error? 

Two possible issues could cause the error:

1. The input postcode did not conform to UK format, e.g. qwerty;
2. The input postcode conformed to UK format, but was not a valid UK postcode, e.g. aa123aa.

For 1, I’m going to add input validation using regex, for 2, I think there is no easy way to prevent a user from entering such postcode, so I’ll handle the error in `getCoord` method before the address information is fetched.

## 1. Input validation using regex

When clicking the Search button, `handleSubmit` method is called which also invokes `getCoord` method. I add an `error` state to store the validation status:

```
if(error === true) {
  // show error message
}
else {
  // remove error message
}
```
A very simple reminder message is placed next to he input field. In `handleSubmit` method, the input is validated as follows: if valid, execute `getCoord` and set `error` state to false; else set `error` state to true. The error message should be shown when `error === true`, and hide when `error === false`. Let take a look at `Weather.js`:

{% gist https://gist.github.com/xiaohan-du/01141c03d5c16754318968bd4572bbfc %}

You may have noticed that here in `handleInputChange` method the `error` state is set to `false`. This is because if postcode is entered again, a user may already have noticed that he/she entered the wrong postcode, therefore the error message is removed immediately when the input state is changed (we don’t want to over-remind the user). Okay, so now the problem is how can we determine whether input is valid and run `getCoord`? We could try to add some regex in `handleValidation` method to address it.

Most UK postcodes follow a certain format thus implementing a regex myself to cover popular cases is possible, but if I want to cover all possible cases, doing it myself becomes infeasible quickly. I found a good solution in [this popular Stack overflow answer](https://stackoverflow.com/questions/164979/regex-for-matching-uk-postcodes), so the following code is added to `handleValidation` method:

```
handleValidation() {
    let regexConst = new RegExp('^([Gg][Ii][Rr] 0[Aa]{2})|((([A-Za-z][0-9]{1,2})|(([A-Za-z][A-Ha-hJ-Yj-y][0-9]{1,2})|(([AZa-z][0-9][A-Za-z])|([A-Za-z][A-Ha-hJ-Yj-y][0-9]?[A-Za-z]))))[0-9][A-Za-z]{2})$');
    return regexConst.test(this.state.postcodeInput);
}
```
As you can see, the regex pattern is very long, so I didn’t want to spend too much time on it and borrowed the Stack overflow answer. Let’s test it:

![Test input validation](https://dev-to-uploads.s3.amazonaws.com/i/h4nort32yku4lytk6uuk.gif)

Good, now issue 1 is resolved. Issue 2 still persists: that is, if the input conforms UK postcode format and bypasses the regex, how can we handle the error?

## 2. Try {fetch API} catch {error}

From the console error we can see that the postcode API returned a 404 error, i.e. postcode not found. A simple try… catch statement can be used to catch the error and show the error message. The `getCoord` method is updated as follows:

```
async getCoord() {
  const postcodeAPI =   `http://api.postcodes.io/postcodes/${this.state.postcodeInput}`;
  let response;
  try {
    response = await fetch(postcodeAPI);
    if (!response.ok) throw new Error('Weather api request failed.');
    await response.json().then(response => {
      this.setState({
        addressData: response,
        coordinate: [response.result.latitude, response.result.longitude]
      });
      let coord = {
        latitude: this.state.coordinate[0],
        longitude: this.state.coordinate[1]
      }
      axios.post('http://localhost:4001/search-location', coord)
        .then((response) => {
          console.log(response);
          this.setState({
            displayResult: true
          });
        }, (error) => {
          console.log(error);
        });
    });
  }
  catch(e) {
    this.setState({error: true});
    console.log(e);
  }
}
```
If an invalid postcode is passed to the API, the response object would contain a property `ok = false`. Therefore this line is added: `if (!response.ok) throw new Error(‘Weather api request failed.’);` to immediately cease the try statement and catch the error. In the `catch` statement the `error` state is set to `true` such that the little reminder is shown next to the input field. Then the error is logged to the console with text ‘Weather api request failed’. No console error would be shown to the user. Let’s test it:

![validation with try...catch](https://dev-to-uploads.s3.amazonaws.com/i/z9mbrihwcfl5939wmcrm.gif)

The 404 error in the console is default browser behaviour, so no need to worry about that. The try…catch statement threw the error and logged the message in the console, and the `error` state made sure that the reminder was displayed.

# What’s next?

Now that the errors are handled, one step closer to a good UK weather app. Obviously the app could look a bit prettier, so in the next article I will get the app decorated and show you how to do it.
Hope it helps! 😁