Improved error handling and responses for rpc failures

This commit is contained in:
Andrew Scott 2022-09-01 22:47:37 -04:00
parent 2ea7920ca2
commit f4eaf5e1fb
Signed by: a
GPG key ID: 3EB62D0BBB8DB381
3 changed files with 45 additions and 45 deletions

View file

@ -4,13 +4,13 @@ package weather;
option go_package = "codeberg.org/andcscott/OpenWeatherMap-gRPC-API/proto";
// Sub-message for exact coordinates
// Sub-message for Coordinates
message Coordinates {
float latitude = 1;
float longitude = 2;
}
// Sub-message to specify location
// Sub-message for RequestLocation
message OneOfLocation {
oneof location_id {
string city = 1;
@ -19,8 +19,11 @@ message OneOfLocation {
}
}
// Used to help the API find info for the correct location. If unspecified, an
// attept is still made but results may be inaccurate.
/* Enum to specify the location type for which data is needed.
* Helps the API find info for the correct location. If unspecified, an
* attept is still made. However, results may be inaccurate if city is used,
* or fail entirely if zip code or coordinates are used.
*/
enum LocationType {
LOCATION_TYPE_UNSPECIFIED = 0;
LOCATION_TYPE_CITY = 1;

View file

@ -13,7 +13,7 @@ import (
// Receives a gRPC request for the current forecast
// Returns a SendCurrent message containing the forecast in JSON
func (s *Server) Current(ctx context.Context, in *pb.RequestCurrent) (*pb.SendCurrent, error) {
log.Println("'Current' function called...")
log.Printf("'Current' called: %v\n", in)
url := "https://api.openweathermap.org/data/2.5/weather?"
lat, lon, err := getLocation(in.Location.String(), s.ApiKey)

View file

@ -12,6 +12,39 @@ import (
"google.golang.org/grpc/status"
)
// Receives a gRPC request for an extended forecast
// Returns a SendFiveDay message with the forecast as JSON
func (s *Server) FiveDay(ctx context.Context, in *pb.RequestFiveDay) (*pb.SendFiveDay, error) {
log.Printf("'FiveDay' called: %v\n", in)
url, err := s.createFiveDayUrl(in)
if err != nil {
return nil, status.Errorf(
codes.InvalidArgument,
fmt.Sprintf("Invalid location or location type: %s, %s\n",
in.Location.String(),
in.LocationType.String()),
)
}
token := "&appid=" + s.ApiKey
res, err := http.Get(url + token)
if err != nil {
log.Printf("Error fetching extended weather: %v\n", err)
}
defer res.Body.Close()
body, err := ioutil.ReadAll(res.Body)
if err != nil {
log.Printf("Error reading extending weather: %v\n", err)
}
return &pb.SendFiveDay{
Payload: string(body),
}, nil
}
// Assembles the OpenWeather API URL for FiveDay
func (s *Server) createFiveDayUrl(in *pb.RequestFiveDay) (string, error) {
var lat, lon float32
@ -31,56 +64,20 @@ func (s *Server) createFiveDayUrl(in *pb.RequestFiveDay) (string, error) {
switch in.LocationType {
case pb.LocationType_LOCATION_TYPE_CITY:
lat, lon, err = getLocation(in.Location.GetCity(), s.ApiKey)
if err != nil {
return "", err
}
case pb.LocationType_LOCATION_TYPE_ZIP_CODE:
lat, lon, err = getZipLocation(in.Location.GetZipCode(), s.ApiKey)
if err != nil {
return "", err
}
case pb.LocationType_LOCATION_TYPE_COORDS:
lat = in.Location.GetCoords().Latitude
lon = in.Location.GetCoords().Longitude
default:
fmt.Println(in.Location.String())
lat, lon, err = getLocation(in.Location.String(), s.ApiKey)
if err != nil {
return "", err
}
}
if err != nil {
return "", err
}
url = url + fmt.Sprintf("lat=%f", lat) + fmt.Sprintf("&lon=%f", lon) + units
return url, nil
}
// Receives a gRPC request for an extended forecast
// Returns a SendExtended message with the forecast in JSON
func (s *Server) FiveDay(ctx context.Context, in *pb.RequestFiveDay) (*pb.SendFiveDay, error) {
log.Println("'FiveDay' function called...")
url, err := s.createFiveDayUrl(in)
if err != nil {
return nil, status.Errorf(
codes.InvalidArgument,
fmt.Sprintf("Invalid location: %s", in.Location.String()),
)
}
token := "&appid=" + s.ApiKey
res, err := http.Get(url + token)
if err != nil {
log.Printf("Error fetching extended weather: %v\n", err)
}
defer res.Body.Close()
body, err := ioutil.ReadAll(res.Body)
if err != nil {
log.Printf("Error reading extending weather: %v\n", err)
}
return &pb.SendFiveDay{
Payload: string(body),
}, nil
}