mirror of https://github.com/k3s-io/k3s
Merge pull request #41416 from smarterclayton/error_panic
Automatic merge from submit-queue (batch tested with PRs 41466, 41456, 41550, 41238, 41416) Don't use json.Marshal when printing error bodies Internal types panic when json.Marshal is called to prevent accidental use. Fixes #40491pull/6/head
commit
2509ab0c7a
|
@ -306,7 +306,7 @@ func TestValidateObjectMetaUpdatePreventsDeletionFieldMutation(t *testing.T) {
|
|||
Old: metav1.ObjectMeta{Name: "test", ResourceVersion: "1"},
|
||||
New: metav1.ObjectMeta{Name: "test", ResourceVersion: "1", DeletionTimestamp: &now},
|
||||
ExpectedNew: metav1.ObjectMeta{Name: "test", ResourceVersion: "1", DeletionTimestamp: &now},
|
||||
ExpectedErrs: []string{"field.deletionTimestamp: Invalid value: \"1970-01-01T00:16:40Z\": field is immutable; may only be changed via deletion"},
|
||||
ExpectedErrs: []string{"field.deletionTimestamp: Invalid value: 1970-01-01 00:16:40 +0000 UTC: field is immutable; may only be changed via deletion"},
|
||||
},
|
||||
"invalid clear deletionTimestamp": {
|
||||
Old: metav1.ObjectMeta{Name: "test", ResourceVersion: "1", DeletionTimestamp: &now},
|
||||
|
|
|
@ -17,8 +17,8 @@ limitations under the License.
|
|||
package field
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"reflect"
|
||||
"strings"
|
||||
|
||||
utilerrors "k8s.io/apimachinery/pkg/util/errors"
|
||||
|
@ -49,14 +49,30 @@ func (v *Error) ErrorBody() string {
|
|||
case ErrorTypeRequired, ErrorTypeForbidden, ErrorTypeTooLong, ErrorTypeInternal:
|
||||
s = fmt.Sprintf("%s", v.Type)
|
||||
default:
|
||||
var bad string
|
||||
badBytes, err := json.Marshal(v.BadValue)
|
||||
if err != nil {
|
||||
bad = err.Error()
|
||||
} else {
|
||||
bad = string(badBytes)
|
||||
value := v.BadValue
|
||||
if reflect.TypeOf(value).Kind() == reflect.Ptr {
|
||||
if reflectValue := reflect.ValueOf(value); reflectValue.IsNil() {
|
||||
value = "null"
|
||||
} else {
|
||||
value = reflectValue.Elem().Interface()
|
||||
}
|
||||
}
|
||||
switch t := value.(type) {
|
||||
case int64, int32, float64, float32, bool:
|
||||
// use simple printer for simple types
|
||||
s = fmt.Sprintf("%s: %v", v.Type, value)
|
||||
case string:
|
||||
s = fmt.Sprintf("%s: %q", v.Type, t)
|
||||
case fmt.Stringer:
|
||||
// anything that defines String() is better than raw struct
|
||||
s = fmt.Sprintf("%s: %s", v.Type, t.String())
|
||||
default:
|
||||
// fallback to raw struct
|
||||
// TODO: internal types have panic guards against json.Marshalling to prevent
|
||||
// accidental use of internal types in external serialized form. For now, use
|
||||
// %#v, although it would be better to show a more expressive output in the future
|
||||
s = fmt.Sprintf("%s: %#v", v.Type, value)
|
||||
}
|
||||
s = fmt.Sprintf("%s: %s", v.Type, bad)
|
||||
}
|
||||
if len(v.Detail) != 0 {
|
||||
s += fmt.Sprintf(": %s", v.Detail)
|
||||
|
|
|
@ -90,7 +90,8 @@ func TestErrorUsefulMessage(t *testing.T) {
|
|||
for _, part := range []string{
|
||||
"foo", ErrorTypeInvalid.String(),
|
||||
"Baz", "Qux", "Inner", "KV", "detail",
|
||||
"1", "aoeu", "asdf", "Billy", "2",
|
||||
"1", "aoeu", "Billy", "2",
|
||||
// "asdf", TODO: reenable once we have a better nested printer
|
||||
} {
|
||||
if !strings.Contains(s, part) {
|
||||
t.Errorf("error message did not contain expected part '%v'", part)
|
||||
|
|
Loading…
Reference in New Issue