Providing this snippet from the AWS docs
func main() {
sess := session.Must(session.NewSessionWithOptions(session.Options{
SharedConfigState: session.SharedConfigEnable,
}))
// Create DynamoDB client
svc := dynamodb.New(sess)
// snippet-end:[dynamodb.go.read_item.session]
// snippet-start:[dynamodb.go.read_item.call]
tableName := "Movies"
movieName := "The Big New Movie"
movieYear := "2015"
result, err := svc.GetItem(&dynamodb.GetItemInput{
TableName: aws.String(tableName),
Key: map[string]*dynamodb.AttributeValue{
"Year": {
N: aws.String(movieYear),
},
"Title": {
S: aws.String(movieName),
},
},
})
if err != nil {
log.Fatalf("Got error calling GetItem: %s", err)
}
// snippet-end:[dynamodb.go.read_item.call]
// snippet-start:[dynamodb.go.read_item.unmarshall]
if result.Item == nil {
msg := "Could not find '" + *title + "'"
return nil, errors.New(msg)
}
item := Item{}
err = dynamodbattribute.UnmarshalMap(result.Item, &item)
if err != nil {
panic(fmt.Sprintf("Failed to unmarshal Record, %v", err))
}
fmt.Println("Found item:")
fmt.Println("Year: ", item.Year)
fmt.Println("Title: ", item.Title)
fmt.Println("Plot: ", item.Plot)
fmt.Println("Rating:", item.Rating)
// snippet-end:[dynamodb.go.read_item.unmarshall]
}
My question is the following:
In the first time we try and get an item from the database (dynamoDB in this example) and we find an error, the snippet does a fatal log but continues with the program.
In the second case where result.Item
is empty, we return an error message to the user.
Thirdly however, when the casting to the variable of result.Item
fails, we panic
Is this a good approach? More specifically, why are we not using panic
for the db query where we request the Item?
I do understand that the second error is something we can gracefully error out of but why not do that for all cases? Is there a good reason we use panic
in the third example and if so, why not panic on the first case too? Or better yet, why not return a graceful error message for all three of the cases?