1
0
mirror of https://github.com/golang/go synced 2024-11-25 00:37:57 -07:00

Propagate error to the caller in json.Marshal. Fixes issue 445.

R=rsc, imkrasin
CC=golang-dev
https://golang.org/cl/179125
This commit is contained in:
Ivan Krasin 2010-01-06 07:25:17 -08:00 committed by Russ Cox
parent 4846702db4
commit e324e4099f
2 changed files with 21 additions and 6 deletions

View File

@ -366,11 +366,9 @@ func writeStruct(w io.Writer, val *reflect.StructValue) os.Error {
for i := 0; i < val.NumField(); i++ { for i := 0; i < val.NumField(); i++ {
fieldValue := val.Field(i) fieldValue := val.Field(i)
fmt.Fprintf(w, "%q:", typ.Field(i).Name) fmt.Fprintf(w, "%q:", typ.Field(i).Name)
if err := writeValue(w, fieldValue); err != nil { if err := writeValue(w, fieldValue); err != nil {
return err return err
} }
if i < val.NumField()-1 { if i < val.NumField()-1 {
fmt.Fprint(w, ",") fmt.Fprint(w, ",")
} }
@ -398,14 +396,19 @@ func writeValue(w io.Writer, val reflect.Value) (err os.Error) {
case *reflect.StructValue: case *reflect.StructValue:
err = writeStruct(w, v) err = writeStruct(w, v)
case *reflect.ChanValue, case *reflect.ChanValue,
*reflect.PtrValue,
*reflect.UnsafePointerValue: *reflect.UnsafePointerValue:
err = &MarshalError{val.Type()} err = &MarshalError{val.Type()}
case *reflect.InterfaceValue: case *reflect.InterfaceValue:
if v.IsNil() { if v.IsNil() {
fmt.Fprint(w, "null") fmt.Fprint(w, "null")
} else { } else {
err = &MarshalError{val.Type()} err = writeValue(w, v.Elem())
}
case *reflect.PtrValue:
if v.IsNil() {
fmt.Fprint(w, "null")
} else {
err = writeValue(w, v.Elem())
} }
default: default:
value := val.(reflect.Value) value := val.(reflect.Value)

View File

@ -175,6 +175,12 @@ type marshalTest struct {
out string out string
} }
type MTE string
type OneField struct {
a int
}
var marshalTests = []marshalTest{ var marshalTests = []marshalTest{
// basic string // basic string
marshalTest{nil, "null"}, marshalTest{nil, "null"},
@ -201,6 +207,9 @@ var marshalTests = []marshalTest{
`{"a":1,"b":"hello"}`, `{"a":1,"b":"hello"}`,
}, },
marshalTest{map[string][]int{"3": []int{1, 2, 3}}, `{"3":[1,2,3]}`}, marshalTest{map[string][]int{"3": []int{1, 2, 3}}, `{"3":[1,2,3]}`},
marshalTest{map[string]*MTE{"hi": nil}, `{"hi":null}`},
marshalTest{map[string]interface{}{"hi": 3}, `{"hi":3}`},
marshalTest{&OneField{3}, `{"a":3}`},
} }
func TestMarshal(t *testing.T) { func TestMarshal(t *testing.T) {
@ -224,11 +233,14 @@ type marshalErrorTest struct {
error string error string
} }
type MTE string type ChanVal struct {
C chan int
}
var marshalErrorTests = []marshalErrorTest{ var marshalErrorTests = []marshalErrorTest{
marshalErrorTest{map[chan int]string{make(chan int): "one"}, "json cannot encode value of type map[chan int] string"}, marshalErrorTest{map[chan int]string{make(chan int): "one"}, "json cannot encode value of type map[chan int] string"},
marshalErrorTest{map[string]*MTE{"hi": nil}, "json cannot encode value of type *json.MTE"}, marshalErrorTest{make(chan int, 100), "json cannot encode value of type chan int"},
marshalErrorTest{new(ChanVal), "json cannot encode value of type chan int"},
} }
func TestMarshalError(t *testing.T) { func TestMarshalError(t *testing.T) {