Step 14: Handle Errors Gracefully

Step 14: Handle Errors Gracefully

If you try the pass an invalid city name to your /weather slash command, we’ll receive the following error in our server log:

inline

This is happening because we aren’t appropriately handling errors. In an ideal scenario, if a user was to pass an invalid city name to the /weather slash command our server should respond back a message informing users of the error

1. Update openWeatherApi() in index.js

  • Update the openWeatherApi() to reflect the code below:
async function openWeatherApi (query) {
  try {
    const url = 'https://api.openweathermap.org/data/2.5/weather'
    const apiKey = process.env.OPEN_WEATHER_API_KEY

    // make api request using axios
    const response = await axios.get(url, {
      params: {
        appid: apiKey,
        q: query,
        units: 'imperial'
      }
    })

    console.log(response)
    return response.data
  } catch (e) {
    console.log(e)

    // "throw" error, which will be "caught"
    // by the function that called openWeatherApi
    throw new Error('City not found')
  }
}

Here’s a summary of the update:

  • In the catch(){} part of our try..catch block we are using throw to forward our error to the function that called openWeatherApi() - we are doing this because we want to make the app.post(/weather...) route handler aware that an error occurred during our API request to OpenWeather

  • We are following the JavaScript best practice of creating an Error object (using the new keyword) when constructing errors; we are passing a message to provide additional context around the error

2. Update app.post(/weather...) in index.js

Now that we’ve made openWeatherApi() throw any errors it encounters, our app.post(/weather...) route handle with then catch those errors in its own try..catch block`

  • Update the app.post(/weather...) to reflect the code below:
app.post('/weather', async (req, res) => {
  try {
    console.log(req.body)

    // respond with an OK to sender within 3 secs
    // as required by Slack for delayed responses
    // documentation: https://api.slack.com/slash-commands#responding_response_url
    res.json()

    // extract city passed in as a parameter to
    // our slash command (/weather cityName)
    const query = req.body.text

    // making API request via openWeatherApi function
    const response = await openWeatherApi(query)

    // print out OpenWeather API
    // response to the console
    console.log(response)

    // Create a forecast based on info
    // received from OpenWeather
    const forecast =
      `Current temperature in ${query} is ${response.main.temp} degrees with a high of ${response.main.temp_max} degrees and a low of ${response.main.temp_min} degrees`

    // construct an object (according to Slack API docs)
    // that will be used to send a response
    // back to Slack
    const data = {
      'response_type': 'in_channel',
      'text': forecast
    }

    // make a POST request (with axios) using "response_url"
    // to complete our "delayed response" as
    // per the Slack API docs
    axios.post(req.body.response_url, data)

    // res.json(data)
  } catch (e) {
    console.log(e)

    // construct an error response to send
    // to Slack in the case of the user
    // sending an invalid city

    const errorResponse = {
      'response_type': 'in_channel',
      'text': '[ADD ANY SLACK EMOJI CODE HERE] Oh oh, there was a problem with your last request. Please make sure you enter a valid city name.'
    }

    axios.post(req.body.response_url, errorResponse)
  }
})

Here’s a summary of the update:

  • In the catch(){} portion of openWeatherApi() we are constructing an object that will contain our response to Slack (structure of this object is based on Slack API docs); in the "text" section of the object, we are sending a helpful message to users so they can take corrective action

  • Lastly, we’re using axios to make a POST request to the response_url and send the errorResponse object that contains our message

3. Try your /weather slash command with an invalid city name

  • Restart your Express server and go back to your development workspace on Slack and try the /weather slash command with an invalid city name such as /weather yolo town

  • After submitting the slash command with an invalid city), an informative error message should be displayed in Slack

inline