WordPress.org

Make WordPress Core

Opened 2 years ago

Closed 2 years ago

Last modified 14 months ago

#41370 closed defect (bug) (fixed)

REST API: Attempting to create an existing term yields HTTP 500

Reported by: jnylen0 Owned by: kadamwhite
Milestone: 4.9 Priority: normal
Severity: normal Version: 4.7
Component: REST API Keywords: good-first-bug has-unit-tests has-patch commit
Focuses: rest-api Cc:
PR Number:

Description

Reported at https://github.com/WordPress/gutenberg/pull/1490. I haven't had time to investigate yet, but this should be a fairly quick win.

HTTP 5xx error codes should be reserved for unexpected server errors like database failures, out of memory, etc. This one should be 400 Bad Request or maybe 409 Conflict instead.

Attachments (2)

41370.patch (759 bytes) - added by alibasheer 2 years ago.
41370.2.patch (1.8 KB) - added by shooper 2 years ago.
Returns HTTP 409. Includes Unit Tests.

Download all attachments as: .zip

Change History (21)

This ticket was mentioned in Slack in #core by flixos90. View the logs.


2 years ago

@alibasheer
2 years ago

#2 @alibasheer
2 years ago

  • Keywords needs-testing added; needs-patch removed

Hello @jnylen0,

I added patch 41370.patch, this is my first patch, please let me know your feedback if I am doing it right. Here are my thoughts:

  • I think it is better to return 409 Conflict as it is trying to create existing term, but I checked what you are returning in other cases like when creating existing post, or existing user and found you are sending 400 Bad Request. I ended up setting this to 400 Bad Request
  • I couldn't fix the status without affecting the returned error structure. It was returning the term id in the data directly, but now I am returning an array of 2 elements in the data, the term_id and status

#3 @guzzilar
2 years ago

Agree on this. I was testing request to /wp-json/wp/v2/categories and found that it returns status 500 error when attempting to create an existing term.

Tested on

  • WP: 4.9-alpha-40870-src
  • REST URL: /wp-json/wp/v2/categories
  • Request Body:
    • name: "test"

Try post this twice and you will get

  • Response Status: 500
  • Response Body:
    {
        "code": "term_exists",
        "message": "A term with the name provided already exists with this parent.",
        "data": 3
    }
    

#4 @guzzilar
2 years ago

@alibasheer I was checking at wp-includes/taxonomy.php: line 1990 on function wp_insert_term().

Would it be better if we change all of return new WP_Error(); in that function to return bad_request 400 instead of 500?
Seems all of WP_Error in this function shouldn't be 500 neither.

#5 @guzzilar
2 years ago

Hi @alibasheer
Sorry, I still can't find the way to patch code in (also new here too 😁).
But from your patch, if you want to make it to be 400 status code, you can simply add status array in the first param of $term->add_data();

So from

<?php

$term->add_data( $existing_term->term_id, 'term_exists' );

Could be

<?php

$term->add_data( array( 'status' => 400, 'existing_term_id' => $existing_term->term_id ), 'term_exists' );

You will get an output

{
    "code": "term_exists",
    "message": "A term with the name provided already exists with this parent.",
    "data": {
        "status": 400,
        "existing_term_id": 1
    }
}

with status 400 Bad Request.

Sorry that I can't help patch it by myself.

@shooper
2 years ago

Returns HTTP 409. Includes Unit Tests.

#6 @shooper
2 years ago

  • Keywords has-unit-tests has-patch added; needs-unit-tests needs-testing removed

Looked at @alibasheer's patch and wrote an updated one that returns an HTTP 409 if the term already exists.

Unit test also included. The only thing I wasn't quite sure of is that I put the unit tests in the rest-categories-controller.php. I did this as it already had the test to create a category, so this was an easy addition. Not sure if it should have been somewhere more generic though. Open to suggestions.

This ticket was mentioned in Slack in #core by shooper. View the logs.


2 years ago

This ticket was mentioned in Slack in #core-restapi by shooper. View the logs.


2 years ago

This ticket was mentioned in Slack in #core-restapi by shooper. View the logs.


2 years ago

#10 @kadamwhite
2 years ago

  • Milestone changed from Future Release to 4.9
  • Owner set to kadamwhite
  • Status changed from new to accepted

#11 @kadamwhite
2 years ago

  • Keywords commit added

#12 @kadamwhite
2 years ago

  • Resolution set to fixed
  • Status changed from accepted to closed

In 41737:

REST API: Return 409 status when attempting to create an existing term.

Fixes an issue where submitting a well-formed request to create a term inappropriately returns a 500 error status if that term already exists.
HTTP 5xx error codes should be reserved for unexpected server errors, so "409 Conflict" is a more appropriate response.

Props alibasheer, guzzilar, shooper.
Fixes #41370.

#13 @coleh
2 years ago

Any reason as to why the existing term ID is no longer returned? Previously when going to create a term if it exists on the site you are trying to post to, it will just return the error along with the term ID so you can pass that along when creating a post so it assigns the correct taxonomy ID. This stopped returning.

This ticket was mentioned in Slack in #core by shooper. View the logs.


2 years ago

#15 @shooper
2 years ago

@coleh Since this change has gone live, I've opened a new ticket for it with a proposed patched. See #42600.

#16 @rachelbaker
2 years ago

In 42350:

REST API: Add existing term_id to the error data object when attempting to create a duplicate term.

Props shooper, coleh.
Fixes #42597. See #41370.

#17 @rachelbaker
2 years ago

In 42354:

REST API: Correct HTTP status code in error for requests to create a duplicate term.

The 409 error code is intended for situations where it is expected that the user will resolve the conflict and resubmit the same request. We use 400 error codes for other routes when a duplicate request is made. The 400 status code tells the user they need to modify their request for it to be successful.

Props shooper.
Fixes #42781. See #41370.

#18 @jorbin
23 months ago

In 42578:

REST API: Add existing term_id to the error data object when attempting to create a duplicate term.

Merges [42350] into 4.9

Props shooper, coleh, rachelbaker.
Fixes #42597. See #41370.

#19 @danielbachhuber
14 months ago

In 43756:

REST API: Correct HTTP status code in error for requests to create a duplicate term.

The 409 error code is intended for situations where it is expected that the user will resolve the conflict and resubmit the same request. We use 400 error codes for other routes when a duplicate request is made. The 400 status code tells the user they need to modify their request for it to be successful.

Props shooper.
Merges [42354] to the 5.0 branch.
Fixes #42781. See #41370.

Note: See TracTickets for help on using tickets.