WordPress.org

Make WordPress Core

Opened 10 months ago

Last modified 10 months ago

#46191 new defect (bug)

WP_REST_Request::has_valid_params() should utilize get_error_messages() and not get_error_message(). Unexpected behavior occurs when you try to WP_Error->add() in the REST API

Reported by: tmfespresso Owned by:
Milestone: Awaiting Review Priority: normal
Severity: normal Version: 4.4
Component: REST API Keywords: needs-patch
Focuses: rest-api Cc:
PR Number:

Description

This is best illustrated via some code that attempts to extend the REST API, please see the comments above CoffeeApi->validateBeans().

<?php
class CoffeeApi {

    // CONTEXT ONLY: this is fine and provided for context 
    public function registerRoutes()
    {
        $version = '1';
        $namespace = 'coffee/v' . $version;
        $base = 'espresso';

        register_rest_route( $namespace, '/' . $base,
            [
                [
                    'methods'  => \WP_REST_Server::READABLE, // GET
                    'callback' => [$this, 'statusCheck'],
                    'permission_callback' => [$this, 'authorize'],
                ],
                [
                    'methods'  => \WP_REST_Server::CREATABLE, // POST
                    'callback' => [$this, 'createOrUpdate'],
                    'permission_callback' => [$this, 'authorize'],
                    'args' => array(
                        'beanId' => array(
                            'validate_callback' => [$this, 'validateBeans']
                        ),
                    ),
                ],
            ]
        );
    }

    // CONTEXT ONLY: this is fine and provided for context 
    public function createOrUpdate(\WP_REST_Request $request)
    {
        $parameters = $request->get_json_params();
        // TODO: pretend stuff happens here 
        return rest_ensure_response( 'SUCCESS: Record created.' );

    }

    /**
    * WARNING: this does not result in the expected behavior
    *
    * TEST CASE: the parameter tested here is non-numeric and fails the first condition 
    *
    * EXPLANATION OF PROBLEM: 
    * Because of https://github.com/WordPress/WordPress/blob/master/wp-includes/rest-api/class-wp-rest-request.php#L878 
    * utilizing get_error_message() instead of get_error_messages(), only 'Bean data is invalid.' gets returned. 
    * E.g.
    *
    * {"code":"rest_invalid_param","message":"Invalid parameter(s): merchantAccountId","data":{"status":400,"params":
    * {"merchantAccountId":"User data is invalid."}}}
    *
    * If get_error_messages() is used, the error response looks like this:
    * {"code":"rest_invalid_param","message":"Invalid parameter(s): merchantAccountId","data":{"status":400,"params":
    * {"merchantAccountId":["User data is invalid.","Merchant Account ID must be numeric."]}}}
    ** / 
    public function validateBeans($rawBeanId){

        $userError = new \WP_Error( 'rest_invalid_validate_beans', esc_html__( 'Bean data is invalid.', 'coffee-api' ), array( 'status' => 400 ) );

        // this gets ignored in the REST API returned errors
        if(!is_numeric( $rawBeanId )){
            $userError->add('rest_invalid_validate_beans', esc_html__( 'Bean data must be numeric.', 'coffee-api' ));
            return $userError;
        }

        // if you get here, this also gets ignored in the REST API returned errors
        if(!$this->otherCondition()){
            $userError->add('rest_invalid_validate_beans', esc_html__( 'Fail for funsies.', 'coffee-api' ));
            return $userError;
        }
    
        return true;
    }
}

Change History (2)

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


10 months ago

#2 @pento
10 months ago

  • Version changed from trunk to 4.4
Note: See TracTickets for help on using tickets.