fix(12.2): close code-review blockers on uploads, JSON caps, and pivot fill
Keep form save behind in-flight uploads, make retries idempotent via X-Upload-Id, cap remaining JSON bodies, and surface pending pivot type errors instead of zeroing them. Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -466,7 +466,7 @@ func (s *service) settingsGet(w http.ResponseWriter, r *http.Request) {
|
||||
|
||||
func (s *service) settingsPut(w http.ResponseWriter, r *http.Request) {
|
||||
s.protectSetting(w, r, func(setting *CompiledSetting) {
|
||||
body, err := decodeObject(r)
|
||||
body, err := s.decodeCappedObject(w, r)
|
||||
if err != nil {
|
||||
writeCRUDError(w, err)
|
||||
return
|
||||
@@ -587,7 +587,7 @@ func (s *service) relationMutation(w http.ResponseWriter, r *http.Request, link
|
||||
writeCRUDError(w, err)
|
||||
return
|
||||
}
|
||||
in, err := decodeRelationMutation(r)
|
||||
in, err := s.decodeCappedRelationMutation(w, r)
|
||||
if err != nil {
|
||||
writeCRUDError(w, err)
|
||||
return
|
||||
@@ -611,11 +611,19 @@ func (s *service) relationMutation(w http.ResponseWriter, r *http.Request, link
|
||||
}
|
||||
|
||||
func decodeRelationMutation(r *http.Request) (RelationMutationInput, error) {
|
||||
dec := json.NewDecoder(r.Body)
|
||||
return decodeRelationMutationBody(r.Body)
|
||||
}
|
||||
|
||||
func decodeRelationMutationBody(body io.Reader) (RelationMutationInput, error) {
|
||||
dec := json.NewDecoder(body)
|
||||
dec.UseNumber()
|
||||
dec.DisallowUnknownFields()
|
||||
var in RelationMutationInput
|
||||
if err := dec.Decode(&in); err != nil {
|
||||
var tooBig *http.MaxBytesError
|
||||
if errors.As(err, &tooBig) {
|
||||
return RelationMutationInput{}, err
|
||||
}
|
||||
return RelationMutationInput{}, relationInvalid("body", "The request body is invalid.")
|
||||
}
|
||||
var trailing any
|
||||
@@ -625,6 +633,10 @@ func decodeRelationMutation(r *http.Request) (RelationMutationInput, error) {
|
||||
return in, nil
|
||||
}
|
||||
|
||||
func (s *service) decodeCappedRelationMutation(w http.ResponseWriter, r *http.Request) (RelationMutationInput, error) {
|
||||
return decodeRelationMutationBody(http.MaxBytesReader(w, r.Body, s.jsonCap()))
|
||||
}
|
||||
|
||||
func (s *service) relations() (RelationService, error) {
|
||||
db, err := s.db()
|
||||
if err != nil {
|
||||
@@ -758,7 +770,7 @@ func (s *service) create(w http.ResponseWriter, r *http.Request) {
|
||||
writeCRUDError(w, err)
|
||||
return
|
||||
}
|
||||
body, err := decodeObject(r)
|
||||
body, err := s.decodeCappedObject(w, r)
|
||||
if err != nil {
|
||||
writeCRUDError(w, err)
|
||||
return
|
||||
@@ -792,7 +804,7 @@ func (s *service) update(w http.ResponseWriter, r *http.Request) {
|
||||
writeCRUDError(w, err)
|
||||
return
|
||||
}
|
||||
body, err := decodeObject(r)
|
||||
body, err := s.decodeCappedObject(w, r)
|
||||
if err != nil {
|
||||
writeCRUDError(w, err)
|
||||
return
|
||||
@@ -816,7 +828,7 @@ func (s *service) bulkDelete(w http.ResponseWriter, r *http.Request) {
|
||||
if !s.operationDeclared(w, r, cc, "bulk-delete") {
|
||||
return
|
||||
}
|
||||
in, err := decodeBulk(r)
|
||||
in, err := s.decodeCappedBulk(w, r)
|
||||
if err != nil {
|
||||
writeCRUDError(w, err)
|
||||
return
|
||||
@@ -836,15 +848,27 @@ func (s *service) bulkDelete(w http.ResponseWriter, r *http.Request) {
|
||||
}
|
||||
|
||||
func decodeBulk(r *http.Request) (BulkDeleteInput, error) {
|
||||
dec := json.NewDecoder(r.Body)
|
||||
return decodeBulkBody(r.Body)
|
||||
}
|
||||
|
||||
func decodeBulkBody(body io.Reader) (BulkDeleteInput, error) {
|
||||
dec := json.NewDecoder(body)
|
||||
dec.UseNumber()
|
||||
var in BulkDeleteInput
|
||||
if err := dec.Decode(&in); err != nil {
|
||||
var tooBig *http.MaxBytesError
|
||||
if errors.As(err, &tooBig) {
|
||||
return BulkDeleteInput{}, err
|
||||
}
|
||||
return BulkDeleteInput{}, &ValidationError{Details: map[string]any{"body": []string{"The request body is invalid."}}}
|
||||
}
|
||||
return in, nil
|
||||
}
|
||||
|
||||
func (s *service) decodeCappedBulk(w http.ResponseWriter, r *http.Request) (BulkDeleteInput, error) {
|
||||
return decodeBulkBody(http.MaxBytesReader(w, r.Body, s.jsonCap()))
|
||||
}
|
||||
|
||||
func (s *service) deleteRecord(w http.ResponseWriter, r *http.Request) {
|
||||
s.protect(w, r, func(cc *CompiledController) {
|
||||
if !s.operationDeclared(w, r, cc, "delete") {
|
||||
|
||||
Reference in New Issue
Block a user