How to handle errors in Zapier? - php

I am building an integration with Zapier (https://zapier.com/platform) and I want to throw an error but it seems like it's not working properly.
My authentication code (dumbed down for the purpose of this post):
if($_POST['api_key'] === $row['api_key']) {
$array = ['success' => 'yes'];
echo json_encode($array);
} else {
echo "Sorry but that is the invalid API token. Please try something else";
}
When I try to test that in the Zapier developer platform, I get this message from them:
Error parsing response. We got: "Sorry but that is the invalid API token. Please try something else". This is likely a problem with the app. Please contact support at contact#zapier.com
But Zapier wants me to throw an error that does not have the "Error parsing response" and "This is likely a problem with the app..." parts....
How can I fix this?

Simply sending a message that the auth was unsuccessful isn't enough - you need to also send the appropriate HTTP response code. In this case, you probably want 403 or 401. I'm not sure how to do that, but there plenty of questions that'll point you in the right direction.
Additionally, you probably want to send back JSON rather than plain text. This could be as simple as: {"message": "invalid token"}. This'll help the client better surface that info to the user.

Related

Woocommerce webhook response 200 message The Rest API is unavailable

When woocommerce (webhook) send a success message (200) but the body contain the below
{
"errors": {
"rest_api_unavailable": [
"The Rest API is unavailable."
]
},
"error_data": []
}
Has anyone happened this error?
Thanks in advance
I did some additional testing on the site I was experiencing this on and narrowed it down to define('ALTERNATE_WP_CRON', true) being set in wp-config.php. If you have this set, try commenting it out. In my tests, the correct payload was sent every time after commenting this constant out. Also, on a completely different site that I configured the same exact webhook/endpoint on that had no issues, as soon as I set ALTERNATE_WP_CRON to true, it started sending rest_api_unavailable for the payload. Please refer to these links for additional information and bug report:
https://github.com/woocommerce/woocommerce/pull/26878
https://github.com/woocommerce/woocommerce/issues/28363

php webhook not responding to Stripe test event

I've setup a basic webhook php page as modeled on the stripe documentation and listed below. When I send a test event from the Stripe webhooks dashboard, stripe responds "Test webhook sent successfully" with a blankk reponse. However, the output log file is not written to, no email is sent and there is nothing logged to the http server error log or the php error log. My php version is 5.3.3. What am I doing wrong?
<?php
error_reporting(15);
// Set your secret key: remember to change this to your live secret key in production
// See your keys here: https://dashboard.stripe.com/account/apikeys
require_once('vendor/autoload.php');
\Stripe\Stripe::setApiKey("secret_test_key");
$handle = fopen("webhook.log","a");
// Retrieve the request's body and parse it as JSON
$input = file_get_contents("php://input");
$event_json = json_decode($input);
// Do something with $event_json
if (fwrite($handle, $event_json) === FALSE) {
mail("mike#example.com","Cannot write to webhook.log","");
echo "Cannot write to webhook.log";
exit;
}
mail('mike#example.com','Webhook Event',$event_json);
header(':', true, 200);
//http_response_code(200); // PHP 5.4 or greater
?>
You have a few potential problems. As a quick rule of thumb, the best way to debug this is to start by triggering the event yourself, which you can do simply by loading up your webhook url in a browser yourself. Then you can test it directly and make sure it is doing what you expect it to be doing. There are obviously two possibilities:
Stripe is not triggering your webhook handler for some reason
Your handler is not properly logging itself
The latter first: it could be that Stripe is triggering your handler but it isn't logging that fact successfully. This would mean that both your email logging and file logging are failing. That is actually quite possible. Email logging with the mail function is actually very unreliable, unless you know for a fact that it works. Mail sent with the mail function is dropped silently by most modern email systems (gmail, etc) unless you have your DNS records properly configured, which most people don't. So unless you know for sure that your mail attempt is working properly, it probably isn't. If you also happen to have a permission issue in your attempt to write to a log file (which is not uncommon for a newly setup server), your logs could simply be failing. The easiest way to check that is to load up the webhook URL in a browser yourself. That way you know it is being triggered, and can know for sure if the issue is improper logging or Stripe not calling your webhook.
If you determine for sure that stripe isn't calling your webhook, the most likely culprit would be an invalid HTTPS certificate. Is your webhook connected via HTTPS (it should be)? If so, is it a valid certificate? You can tell your browser to ignore an invalid certificate when you browse your own site, but stripe will simply refuse to send the request if it encounters an invalid certificate.
If none of the above fixes it then it will be time for more digging, but I would start with those: they are probably the most likely problems.
The solution is that $event_json is an object and the fwrite failed because it expects a string not an object. By converting to an array and then serializing I was able to both write to the log and send the email.
$event_json = (array)json_decode($input);
$event = serialize($event_json);

SoapClient call returns 500 Internal Server Error

I am trying to connect to an API using PHP and its built-in SoapClient. I have checked against the url I was given through the ill-formatted documents the client gave and $client->__getFunctions() returns a list of three functions. HelloWorld($name), which responds with Hello ~name~, shows me that I am communicating with the server through the SoapClient call and the URL is correct.
However, when I try to access one of the other methods that __getFunctions() gives me, even after copy/pasting the XML from the docs and putting in my own credentials, I am still being given an Internal Server Error faultstring and 500 as faultcode from the SoapFault object.
I am sure that it is my own XML string that is causing the issue but I cannot for the life of me figure out how. Reaching out to the API provider directly hasn't proven helpful. This is my first time dealing with Soap/Web Services so I am unsure of where to go from here.
I did wget http//xxx.xxx.xxx?wsdl and it returned me what looks like a valid XML response, the same one I get when I go directly to the url in the browser. What should I be looking into in order to solve this issue? All of the past API's I've dealt with have been JSON/RESTful so I feel out of my element trying to debug PHP errors.
Edit
I have slowly deleted parts of my method call and parts of my XML string, trying to trigger a different error or something in order to find what I need to fix. What I have found is that by not passing in my XML string, I get a valid response from the $client->FunctionCall(...). It's an "this isn't right" message but it's a message! In fact, passing that function ANYTHING for the xml parameter causes the 500 http faultcode/faultstring. Does this mean that my XMl is poorly formatted or does it mean that there is an issue on their end handling requests?
Second Edit
If I make my $client decleration as follows, I get the faultstring Could not connect to host
$opts = array(
'ssl' => array('ciphers'=>'RC4-SHA')
);
$client = new SoapClient($CREDS['orderingWSDL'], array (
"encoding"=>"ISO-8859-1",
'stream_context' => stream_context_create($opts),
'exceptions'=>true,
));
I am getting more confused the longer I try to fix this.
Sometimes a 500 status coming from a SOAP service could be a SoapFault exception being thrown. To help your troubleshooting, you'll want to be able to inspect both your request XML, and the response XML.
Put your code in try/catch blocks, and use $client->__getLastRequest() and $client->__getLastResponse() to inspect the actual XML.
Example:
$client = new SoapClient('http//xxx.xxx.xxx?wsdl', array('soap_version'=>SOAP_1_1,'trace' => 1,'exceptions' => true));
try {
$response = $client->someFunction();
var_dump($response);
} catch (Exception $e) {
var_dump($e->getMessage());
var_dump($client->__getLastRequest());
var_dump($client->__getLastResponse());
}

SimpleXMLElement - HTTP status code?

I'm working with the PHP Steam Condenser library, to grab some Steam details about a user. I've successfully implemented this and everything is working. However I started to notice an error being thrown every so often, from Steam Condenser.
What's happening is, when I call the SteamId class with a param, the library generates a URL and makes a request to it, using SimpleXMLElement (as can be seen here). Now most of the time, the URL returns XML and so my application works fine, however every so often Steam throws back a 503 Service Unavailable back, causing it to fail.
try {
return #new SimpleXMLElement($url, 0, true);
} catch (Exception $e) {
$errorMessage = "XML could not be parsed: " . $e->getMessage();
if ((float) phpversion() < 5.3) {
throw new SteamCondenserException($errorMessage, 0);
} else {
throw new SteamCondenserException($errorMessage, 0, $e);
}
}
In my cause, the PHP version is correct, so it throws the bottom custom Exception:
SteamCondenserException
XML could not be parsed: String could not be parsed as XML
/home/user/public_html/acme/vendor/koraktor/steam-condenser/lib/steam/community/XMLData.php (Line 38)
Although this is technically the correct exception, it isn't very meaningful since the request was just "Unavailable" and therefore couldn't gather the XML.
How would I go about editing this code to first check what the status code of the request is, if it's a 302 or 200 (since it redirects), then proceed to check the XML, otherwise if it's a 503, respond with a more genuine error (The Steam Community API is currently down) - or something.
I've Google'd my ass off, but can't see anything. Ideally I'd like it all to be done in the same request, since Steam can be a little slow sometimes.
Cheers
Don't use SimpleXMLElement to also do the HTTP request.
Use curl (because it's fast) to fetch the XML plain-text and SimpleXML to parse it.
That way you can separate service availability from transmission errors (or XML errors).

Proper mechanism for sending PHP errors to the client

Greetings,
I was trying to discover a proper way to send captured errors or business logic exceptions to the client in an Ajax-PHP system. In my case, the browser needs to react differently depending on whether a request was successful or not. However in all the examples I've found, only a simple string is reported back to the browser in both cases. Eg:
if (something worked)
echo "Success!";
else
echo "ERROR: that failed";
So when the browser gets back the Ajax response, the only way to know if an error occurred would be to parse the string (looking for 'error' perhaps). This seems clunky.
Is there a better/proper way to send back the Ajax response & notify the browser of an error?
Thank you.
You could send back an HTTP status code of 500 (Internal server error) , and then include the error message in the body. Your client AJAX library should then handle it as an error (and call an appropriate callback etc.) without you having to look for strings in the response.
I generally send back a JSON response like this:
$response = array('status' => 'error', 'message' => 'an unknown error occured');
if( some_process() ) {
$response['status'] = 'success';
$response['message'] = 'Everything went better than expected.';
} else {
$response['message'] = "Couldn't reticulate splines.";
}
die( json_encode($response) );
So, I can check the status of response.status in my JavaScript and look for a value of "sucess" or "error" and display response.message appropriately.
showing to the user a status of what is happening and what has happened is very important.
I you want to structure your ajax responses, you should look into the json format.
if (something worked)
echo '{ "error": 0 }';
else
echo '{ "error": 1 }';
Once you set foot into the json world, you will be able to send more structured output. For example :
if (something worked)
echo '{ "error": 0 }';
else
echo '{ "error": 1, "code": 889, "desc": "Something bad happened" }';
When you receive this output in javascript, you can transform it into an object and take actions depending on the different keys.
The library json2.js will help you transform your output into an object
Sending the appropriate http headers should do the trick and tell your ajax scripts to execute the right callback. Each javascript framework i know of has a success and error callback for it's XHR requests.
header('HTTP/1.1 500 Internal Server Error');
You can send back a JSON object which contains a custom error code and error message which you can then either handle or display directly to your users:
{
"response": 10,
"message": "The database didn't work or something"
}
It would work for success as well:
{
"response": 1,
"message": "It worked! Yippee!"
}

Categories