Problem/Motivation

This error appears on occasion. Likely needs a defensive check.

TypeError: method_exists(): Argument #1 ($object_or_class) must be of type object|string, int given in method_exists() (line 136 of /var/www/cms/docroot/modules/contrib/post_api/src/Plugin/QueueWorker/PostApiQueueBase.php) #0 /var/www/cms/docroot/modules/contrib/post_api/src/Plugin/QueueWorker/PostApiQueueBase.php(136): method_exists(500, 'getStatusCode') #1 /var/www/cms/docroot/modules/contrib/post_api/src/Form/PostApiQueueForm.php(180): Drupal\post_api\Plugin\QueueWorker\PostApiQueueBase->processQueue() #2 [internal function]: Drupal\post_api\Form\PostApiQueueForm->submitForm(Array, Object(Drupal\Core\Form\FormState)) #3 /var/www/cms/docroot/core/lib/Drupal/Core/Form/FormSubmitter.php(114): call_user_func_array(Array, Array) #4 /var/www/cms/docroot/core/lib/Drupal/Core/Form/FormSubmitter.php(52): Drupal\Core\Form\FormSubmitter->executeSubmitHandlers(Array, Object(Drupal\Core\Form\FormState)) #5 /var/www/cms/docroot/core/lib/Drupal/Core/Form/FormBuilder.php(597): Drupal\Core\Form\FormSubmitter->doSubmitForm(Array,

Steps to reproduce

Proposed resolution

Remaining tasks

User interface changes

API changes

Data model changes

Comments

swirt created an issue. See original summary.

shreya_th’s picture

StatusFileSize
new872 bytes

The error occurs in the code at line 136 of the PostApiQueueBase.php file, where we are using method_exists() with an incorrect argument type i.e. $response_code = (method_exists($response, 'getStatusCode')) ? $response->getStatusCode() : 500;
In this line, we trying to check if the $response object has a method called getStatusCode(). However, the $response variable seems to hold an HTTP response instance, which should already have the getStatusCode() method. Therefore, there's no need to use method_exists() here.
As per my knowledge i think To solve this issue, we can directly call the getStatusCode() method on the $response object.
no need to using method_exists().

dineshkumarbollu’s picture

Hi
In this line $response_code = (method_exists($response, 'getStatusCode')) ? $response->getStatusCode() : 500;
if No response then they are adding $response_code as '500' i.e Internal Server Error, the issue is Response they are getting at line 135 is not a object $response = $this->processItem($item->data);.

mohd sahzad’s picture

StatusFileSize
new1.26 KB

i have created patch for this call to method exists throws an error.

keshavv’s picture

Status: Active » Needs review
swirt’s picture

Status: Needs review » Needs work

Wow. I have never seen such a fast response from so many people. Thanks for all the help.
Patch #2 is targeting the wrong problem. We can't forgo the call to method_exists because sometimes the response is not an object. So, as @dineshkumarbollu explained, removing it does not prevent the problem we would have when calling ->getStatusCode() on something that is not a response object.

I think the defensive check of ` if (!is_int($response)) {` in patch #4 is close, but affirming the indirect thing, instead of affirming the direct thing. What we really want to check is, is the $response we are about to act on an actual \Psr\Http\Message\ResponseInterface So it would be more direct to have the check be

if ($response instanceof ResponseInterface)  {
swirt’s picture

The simplest fix is to replace

$response_code = (method_exists($response, 'getStatusCode')) ? $response->getStatusCode() : 500;
$reason_phrase = (method_exists($response, 'getReasonPhrase')) ? $response->getReasonPhrase() : 'none provided';

with

$response_code = ($response instanceof ResponseInterface) ? $response->getStatusCode() : 500;
$reason_phrase = ($response instanceof ResponseInterface) ? $response->getReasonPhrase() : 'none provided';

  • swirt committed c290b35e on 2.x
    Issue #3382748 Fix call to method exists throws an error
    
swirt’s picture

Status: Needs work » Fixed
swirt’s picture

This will go out with 2.0.4

Status: Fixed » Closed (fixed)

Automatically closed - issue fixed for 2 weeks with no activity.