postmark-php icon indicating copy to clipboard operation
postmark-php copied to clipboard

InvalidArgumentException: Invalid resource type: boolean

Open karlwilbur opened this issue 9 years ago • 3 comments

I am occasionally seeing InvalidArgumentExceptions when sending emails. It appears that Postmark is passing bad values to Guzzle.

"InvalidArgumentException: Invalid resource type: boolean"

Here is my question on SO: http://stackoverflow.com/questions/33085043/postmark-guzzle-invalidargumentexception-invalid-resource-type-boolean

There is also an issue logged in the Guzzle project: https://github.com/guzzle/guzzle/issues/628

karlwilbur avatar Oct 12 '15 15:10 karlwilbur

This turned out to be a character encoding issue on my end (see my SO answer).

Should the Postmark SDK check for such things that would prevent successful interaction with the API? Maybe thrown a character encoding exception?

If that would be helpful to others (it certainly would have saved me a number of hours), I'd be happy to code it up and submit a PR.

karlwilbur avatar Oct 13 '15 02:10 karlwilbur

@karlwilbur Hi Karl, sorry for the confusion on this. I'd love to see an example of how this was fixed, it might be something we can integrate into the library. I would have also expected Guzzle to handle encoding to UTF-8, which is a requirement of JSON, but it sounds like that didn't happen.

atheken avatar Oct 13 '15 13:10 atheken

No, Guzzle doesn't make any changes to the input.

If you follow the stack trace in my SO post, you see that the data in the $body param to PostmarkClientBase::processRestRequest just is pretty much just passed along the line. It gets passed in as the $options['json'] param to GuzzleHttp\Client::createRequest (remember, I'm using the v5.3 client here: https://github.com/guzzle/guzzle/blob/5.3/src/Client.php). In there it hands off to GuzzleHttp\Message\MessageFactory::createRequest which in turn hands it off to GuzzleHttp\Message\MessageFactory::applyOptions where is it run through json_endode().

No change at all to my data that gets passed in ...nor is there any validation of my data. Which is fine. I can accept that it is totally up to me to validate my data. It was yet another time that PHP's poor handling of character encoding took away hours of my life.

My solution was pretty much just:

$html_body = utf8_encode($html_body);
$text_body = utf8_encode($text_body);

I think that maybe in Postmark\PostmarkClientBase::processRestRequest we could do some validation for the json params. We could change line 92 to be something like this:

$options['json'] = static::validateJsonParams($cleanParams);

Then create a new Postmark\PostmarkClientBase::validateJsonParams which could be something like:

public static function validateJsonParams($params) {
  $json = false;
  try {
    $json = json_encode($params);
    if (!$json) {
      $json_error_code = last_json_error();
      switch ($json_error_code) {
        case: JSON_ERROR_NONE
          $json_error_message = "No error has occurred."
          break;
        case: JSON_ERROR_DEPTH
          $json_error_message = "The maximum stack depth has been exceeded."
          break;
        case: JSON_ERROR_STATE_MISMATCH
          $json_error_message = "Invalid or malformed JSON.";
          break;
        case: JSON_ERROR_CTRL_CHAR
          $json_error_message = "Control character error, possibly incorrectly encoded.";
          break;
        case: JSON_ERROR_SYNTAX
          $json_error_message = "Syntax error.";
          break;
        case: JSON_ERROR_UTF8
          $json_error_message = "Malformed UTF-8 characters, possibly incorrectly encoded.";
          break;
        case: JSON_ERROR_RECURSION
          $json_error_message = "One or more recursive references in the value to be encoded.";
          break;
        case: JSON_ERROR_INF_OR_NAN
          $json_error_message = "One or more NAN or INF values in the value to be encoded.";
          break;
        case: JSON_ERROR_UNSUPPORTED_TYPE
          $json_error_message = "A value of a type that cannot be encoded was given.";
          break;
      }
    }
  } catch (Exception $e) {
    $json_error_code = $e->getCode();
    $json_error_message = $e->getMessage();
  }
  if (!$json) {
    $ex = new PostmarkException();
    $ex->httpStatusCode = 400;
    $ex->message = 'Bad Request: There appears to be something wrong with your data syntax.' .
      'This error was "['.$json_error_code.'] '.$json_error_message.'".';
    throw $ex;
  }
  return $params;
}

karlwilbur avatar Oct 13 '15 22:10 karlwilbur