Reputation: 10225
Given the following code:
package main
import (
"encoding/json"
"fmt"
"log"
)
type Employee struct {
Id int "json:id"
}
func main() {
b, err := json.Marshal(&Employee{Id: 2})
if err != nil {
log.Fatal("Couldn't marshal the Employee")
}
fmt.Println(string(b))
}
Can checking for the error be reliably ignored using the _
placeholder since the Employee
struct is well defined. Theoretically it should never fail, so begs the question is it a good practice to ignore this type of error and save a little on this type of boilerplate error checking?
Ignoring would look like so:
package main
import (
"encoding/json"
"fmt"
)
type Employee struct {
Id int "json:id"
}
func main() {
b, _ := json.Marshal(&Employee{Id: 2})
fmt.Println(string(b))
}
Upvotes: 12
Views: 413
Reputation:
Proper error handling is an essential requirement of good software.
Normally your code won't fail. but if user Adds this MarshalJSON
method reciver to your type, it fails:
func (t *Employee) MarshalJSON() ([]byte, error) {
if t.Id == 2 {
return nil, fmt.Errorf("Forbiden Id = %d", t.Id)
}
data := []byte(fmt.Sprintf(`{"Id":%d}`, t.Id))
return data, nil
}
This code Compiles, but fails on purpose just for Id == 2
(The Go Playground):
package main
import (
"encoding/json"
"fmt"
"log"
)
type Employee struct {
Id int "json:id"
}
func main() {
b, err := json.Marshal(&Employee{Id: 2})
if err != nil {
log.Fatal("Couldn't marshal the Employee", err)
}
fmt.Println(string(b))
}
func (t *Employee) MarshalJSON() ([]byte, error) {
if t.Id == 2 {
return nil, fmt.Errorf("Forbiden Id = %d", t.Id)
}
data := []byte(fmt.Sprintf(`{"Id":%d}`, t.Id))
return data, nil
}
Also this code Compiles, but fails (The Go Playground):
package main
import (
"encoding/json"
"fmt"
"log"
)
type Employee struct {
Id int "json:id"
}
func main() {
b, err := json.Marshal(&Employee{Id: 2})
if err != nil {
log.Fatal("Couldn't marshal the Employee")
}
fmt.Println(string(b))
}
func (t Employee) MarshalJSON() ([]byte, error) {
data := []byte(fmt.Sprint(t))
return data, nil
}
Upvotes: 7
Reputation: 828
You can always write your own "wrapper" packages to compose behavior that might otherwise be boilerplate. For example, if you have a logging system set up, you might build a small package that looks like:
package json
import (
"encoding/json"
"log"
)
func TryMarshal(v interface{}) []byte {
b, err := json.Marshal(v)
if err != nil {
log.Println(err)
return nil
}
return b
}
Upvotes: 0