I am developing a JSON endpoint that basically reads data from a server-side COM port into a file (on the server end) when a user sends a GET request to it. The response from the server has to be a properly formed JSON response containing the name of the file where the contents were dumped to. If the COM port takes too long to respond, the file is closed and still considered valid with whatever contents it did read from the COM port. A valid response is still provided.
When the COM port is no longer being fed data, it blocks until the script times out. This results in an error and IIS provides a generic error page on a json endpoint. This is not valid json, but it also does not contain the name of the file where the com data was dumped to.
For your JSON endpoint, you could create a wrapper script that calls your IO script. Set a timeout for your attempt to get a response from it, and then return JSON with either whatever it got from the script, or some custom message if the script timed out.
$timeout = 5; // some reasonable time less than the wrapper script timeout
$data = ['filename' => 'something']; // create the file name
$q = http_build_query($data); // pass it to the IO script
$context = stream_context_create(['http'=> ['timeout' => $timeout]]);
$response = file_get_contents("http://yourserver/io_script.php?$q", false, $context);
echo json_encode($data + ['data' => $response ?: 'no data']);