Skip to content

Commit 51fe840

Browse files
committed
fix: slight refactor to make the error handling more robust on index.js
1 parent efa729e commit 51fe840

File tree

4 files changed

+75
-27
lines changed

4 files changed

+75
-27
lines changed

index.js

Lines changed: 30 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
const express = require('express')
22
const weather = require('./src/weatherAPI.js')
3-
const {requestCityFromIP, requestCoordsFromIP} = require('./src/geoipAPI.js')
3+
const {geolocateFromIP} = require('./src/geoipAPI.js')
44
const anonymizeip = require('./src/anonymizeip.js')
55
var path = require('path');
66

@@ -28,15 +28,16 @@ api.get('/', (req, res) => {
2828
ipAddr: anonymizeip(clientIP),
2929
}
3030

31-
requestCityFromIP(clientIP).then((coords) => {
32-
console.log('Coords obj:', coords)
31+
const weatherResp = geolocateFromIP(clientIP).then((coords) => {
32+
// If the geolocation is successful, format the name of the returned location,
33+
// then call the weather API with the coordinates and timezone.
3334

3435
if ("regionName" in coords && "city" in coords && "country" in coords) {
3536
renderValues.locationName = `${coords.city}, ${coords.regionName}, ${coords.country}`
3637
} else if ("country" in coords) {
3738
if ("city" in coords) {
3839
renderValues.locationName = `${coords.city}, ${coords.country}`
39-
} else if ("region" in coords) {
40+
} else if ("regionName" in coords) {
4041
renderValues.locationName = `${coords.regionName}, ${coords.country}`
4142
} else {
4243
renderValues.locationName = coords.country
@@ -47,12 +48,27 @@ api.get('/', (req, res) => {
4748
renderValues.locationName = coords.regionName
4849
}
4950

50-
// By default, display the weather in Toronto.
51-
return weather("43.7001", "-79.4163", "America/Toronto")
52-
}).then((weatherData) => {
53-
// renderValues.forecast = JSON.stringify(weatherData)
51+
return weather(coords.lat, coords.lon, coords.timezone)
52+
}).catch((coords) => {
53+
// If the geolocation fails, default to Toronto, Ontario, Canada, then call
54+
// the weather API with the coordinates and timezone.
55+
56+
renderValues.locationName = "Toronto, Ontario, Canada"
57+
return weather("43.7", "-79.42", "America/Toronto")
58+
})
59+
60+
weatherResp.then((weatherData) => {
61+
// Once the weather API call is successful, render the index page with the
62+
// template values specified in `renderValues`.
63+
5464
renderValues.forecast = weatherData
5565
res.render('index', renderValues)
66+
}).catch((e) => {
67+
// If the weather API call fails, render the index page with the template
68+
// and the limited values that are available.
69+
70+
console.error("Error in main route:", e)
71+
res.render('index', renderValues)
5672
})
5773
})
5874

@@ -61,19 +77,24 @@ api.get('/geolocate', (req, res) => {
6177
// will send a request to `/geolocate` to get the estimated coordinates
6278
// of the client's IP address. This will then return the coordinates to the
6379
// client, which will use them to call the weather API as it normally would.
64-
geoip(req.ip).then((coords) => {
80+
geolocateFromIP(req.ip).then((coords) => {
6581
res.json(coords)
82+
}).catch((e) => {
83+
res.json({status: 'error', code: 500, message: e.message})
6684
})
6785
})
6886

6987
api.get('/weather', (req, res) => {
7088
const queryParams = req.query
7189
if (!queryParams.lat || !queryParams.lon || !queryParams.timezone) {
7290
res.status(400).send('Missing query parameters. All of the following are required: lat, lon, timezone')
91+
return
7392
}
7493

7594
weather(queryParams.lat, queryParams.lon, queryParams.timezone).then((weatherData) => {
7695
res.json(weatherData)
96+
}).catch((e) => {
97+
res.json({status: 'error', code: 500, message: e.message})
7798
})
7899
})
79100

src/geoipAPI.js

Lines changed: 41 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,16 @@ function buildAPIRequest(ipAddr, fieldsVal) {
2929

3030
}
3131

32+
const defaultCoords = {
33+
status: 'success',
34+
country: 'Canada',
35+
regionName: 'Ontario',
36+
city: 'Toronto',
37+
lat: '43.7',
38+
lon: '-79.42',
39+
timezone: 'America/Toronto',
40+
}
41+
3242
function apiRequest(url) {
3343

3444
return new Promise((resolve, reject) => {
@@ -49,6 +59,7 @@ function apiRequest(url) {
4959
res.on('end', () => {
5060
try {
5161
coordsResponse = JSON.parse(responseData)
62+
// console.log("coordsResponse: ", coordsResponse)
5263

5364
// Because this sample app is used in live demos, we want to
5465
// anonymize the coordinates returned to the client side.
@@ -58,13 +69,17 @@ function apiRequest(url) {
5869
}
5970

6071
if (coordsResponse.status !== 'success') {
61-
throw new Error('API request to `ip-api.com` failed.')
72+
// If our query to the geolocation API endpoint fails,
73+
// return the default coordinates object, which has the
74+
// coordinates and timezone for Toronto, Ontario, Canada.
75+
console.error('API request to `ip-api.com` did not succeed. Rejecting with default coordinates object (Toronto).')
76+
reject(defaultCoords)
6277
} else {
6378
resolve(coordsResponse)
6479
}
6580
} catch (e) {
6681
console.error(e.message)
67-
reject(e)
82+
reject(defaultCoords)
6883
}
6984
})
7085
})
@@ -78,31 +93,43 @@ function apiRequest(url) {
7893
})
7994
}
8095

81-
function requestCoordsFromIP(ipAddr) {
96+
// function requestCoordsFromIP(ipAddr) {
8297

83-
// Validate input and throw an error if the input string isn't a valid IP address.
84-
if (!ipAddrRegex.test(ipAddr)) {
85-
throw new Error('Invalid IP address format')
86-
}
98+
// // Validate input and throw an error if the input string isn't a valid IP address.
99+
// if (!ipAddrRegex.test(ipAddr)) {
100+
// throw new Error('Invalid IP address format')
101+
// }
87102

88-
const url = buildAPIRequest(ipAddr, 'status,country,regionName,city,lat,lon,timezone')
89-
return apiRequest(url)
90-
}
103+
// const url = buildAPIRequest(ipAddr, 'status,country,regionName,city,lat,lon,timezone')
104+
// return apiRequest(url)
105+
// }
106+
107+
// function requestCityFromIP(ipAddr) {
91108

92-
function requestCityFromIP(ipAddr) {
109+
// // Validate input and throw an error if the input string isn't a valid IP address.
110+
// if (!ipAddrRegex.test(ipAddr)) {
111+
// throw new Error('Invalid IP address format')
112+
// }
113+
114+
// const url = buildAPIRequest(ipAddr, 'status,country,regionName,city,lat,lon,timezone')
115+
// return apiRequest(url)
116+
// }
117+
118+
function geolocateFromIP(ipAddr) {
93119

94120
// Validate input and throw an error if the input string isn't a valid IP address.
95121
if (!ipAddrRegex.test(ipAddr)) {
96122
throw new Error('Invalid IP address format')
97123
}
98124

99-
const url = buildAPIRequest(ipAddr, 'status,country,regionName,city')
125+
const url = buildAPIRequest(ipAddr, 'status,country,regionName,city,lat,lon,timezone')
100126
return apiRequest(url)
101127
}
102128

103129

104130

105131
module.exports = {
106-
requestCityFromIP,
107-
requestCoordsFromIP,
132+
// requestCityFromIP,
133+
// requestCoordsFromIP,
134+
geolocateFromIP,
108135
}

src/weatherAPI.js

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -145,7 +145,7 @@ function generateForecast(weatherData) {
145145
dailyForecasts[day] = singleDayForecast
146146
})
147147

148-
console.log(dailyForecasts)
148+
// console.log(dailyForecasts)
149149
return dailyForecasts
150150
}
151151

@@ -182,8 +182,8 @@ function getWeather(lat, lon, timezone) {
182182
timezone: timezone
183183
})
184184

185-
console.log('------------------------------\nQuery parameters:')
186-
console.log(queryParams)
185+
// console.log('------------------------------\nQuery parameters:')
186+
// console.log(queryParams)
187187

188188
const queryString = Object.keys(queryParams).map(key => key + '=' + queryParams[key]).join('&')
189189

views/currentConditions.pug

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ h3 Weather Forecast
22
button(id="geolocate") Get Local Forecast
33
p(id="coords")
44
#forecast
5-
if forecast.current
5+
if forecast && forecast.current
66
if forecast.current.temperature_2m
77
#currentTemperature
88
span(id="currentTempVal") #{forecast.current.temperature_2m[0]}

0 commit comments

Comments
 (0)