mirror of
https://github.com/EGroupware/egroupware.git
synced 2024-11-28 02:43:22 +01:00
return and show in browser JSON parsing errors maybe caused by network problems
server sends HTTP status "400 Bad Request" with JSON payload with "error" and "errno" attributes. error is json_last_error_msg() prefixed with "JSON ". Not yet implemented is resending the request (max. twice) for JSON parsing errors to try to work around network problems
This commit is contained in:
parent
a635ac34b4
commit
2f1333a116
@ -149,9 +149,19 @@ egw.extend('json', egw.MODULE_WND_LOCAL, function(_app, _wnd)
|
||||
this.egw.message.call(this.egw, this.egw.lang('A request to the EGroupware server returned with an error')+': '+_xmlhttp.statusText+' ('+_xmlhttp.status+
|
||||
")\n\n"+this.egw.lang('Please reload the EGroupware desktop (F5 / Cmd+r).')+"\n"+
|
||||
this.egw.lang('If the error persists, contact your administrator for help and ask to check the error-log of the webserver.')+
|
||||
"\n\nURL: "+this.url+"\n"+(_xmlhttp.getAllResponseHeaders() ? _xmlhttp.getAllResponseHeaders().match(/^Date:.*$/m)[0]:''));
|
||||
"\n\nURL: "+this.url+"\n"+(_xmlhttp.getAllResponseHeaders() ? _xmlhttp.getAllResponseHeaders().match(/^Date:.*$/mi)[0]:'')+
|
||||
// if EGroupware send JSON payload with error, errno show it here too
|
||||
(_err === 'error' && _xmlhttp.status === 400 && typeof _xmlhttp.responseJSON === 'object' && _xmlhttp.responseJSON.error ?
|
||||
"\nError: "+_xmlhttp.responseJSON.error+' ('+_xmlhttp.responseJSON.errno+')' : ''));
|
||||
|
||||
this.egw.debug('error', 'Ajax request to', this.url, ' failed: ', _err, _xmlhttp.status, _xmlhttp.statusText);
|
||||
this.egw.debug('error', 'Ajax request to', this.url, ' failed: ', _err, _xmlhttp.status, _xmlhttp.statusText, _xmlhttp.responseJSON);
|
||||
|
||||
// check of unparsable JSON on server-side, which might be caused by some network problem --> resend max. twice
|
||||
if (_err === 'error' && _xmlhttp.status === 400 && typeof _xmlhttp.responseJSON === 'object' &&
|
||||
_xmlhttp.responseJSON.errno && _xmlhttp.responseJSON.error.substr(0, 5) === 'JSON ')
|
||||
{
|
||||
// ToDo: resend request max. twice
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -54,23 +54,36 @@ class Request
|
||||
*
|
||||
* @param string menuaction to call
|
||||
* @param string $input_data is the RAW input data as it was received from the client
|
||||
* @throws \InvalidArgumentException if JSON can not be parsed (json_last_error())
|
||||
* or did not contain request[parameters] array (999)
|
||||
*/
|
||||
public function parseRequest($menuaction, $input_data)
|
||||
{
|
||||
// Remember that we currently are in a JSON request - e.g. used in the redirect code
|
||||
self::$_hadJSONRequest = true;
|
||||
|
||||
if (get_magic_quotes_gpc()) $input_data = stripslashes($input_data);
|
||||
|
||||
$json_data = json_decode($input_data,true);
|
||||
if (is_array($json_data) && isset($json_data['request']) && isset($json_data['request']['parameters']) && is_array($json_data['request']['parameters']))
|
||||
// no or empty payload is eg. used by dynamicly loading tree nodes (uses just GET parameters)
|
||||
if (!isset($input_data) || $input_data === '')
|
||||
{
|
||||
//error_log(__METHOD__.__LINE__.array2string($json_data['request']).function_backtrace());
|
||||
$parameters =& $json_data['request']['parameters'];
|
||||
$parameters = array();
|
||||
}
|
||||
else
|
||||
{
|
||||
$parameters = array();
|
||||
if (get_magic_quotes_gpc()) $input_data = stripslashes($input_data);
|
||||
|
||||
if (($json_data = json_decode($input_data,true)) === null && json_last_error() !== JSON_ERROR_NONE)
|
||||
{
|
||||
throw new \InvalidArgumentException('JSON '.json_last_error_msg(), json_last_error());
|
||||
}
|
||||
elseif (is_array($json_data) && isset($json_data['request']) && isset($json_data['request']['parameters']) && is_array($json_data['request']['parameters']))
|
||||
{
|
||||
//error_log(__METHOD__.__LINE__.array2string($json_data['request']).function_backtrace());
|
||||
$parameters =& $json_data['request']['parameters'];
|
||||
}
|
||||
else
|
||||
{
|
||||
throw new \InvalidArgumentException('Missing request:parameters object', 999);
|
||||
}
|
||||
}
|
||||
// do we have a single request or an array of queued requests
|
||||
if ($menuaction == 'api.queue')
|
||||
|
17
json.php
17
json.php
@ -70,8 +70,11 @@ function ajax_exception_handler($e)
|
||||
// set our own exception handler, to not get the html from eGW's default one
|
||||
set_exception_handler('ajax_exception_handler');
|
||||
|
||||
if (isset($_GET['menuaction']))
|
||||
{
|
||||
try {
|
||||
if (!isset($_GET['menuaction']))
|
||||
{
|
||||
throw new InvalidArgumentException('Missing menuaction GET parameter', 998);
|
||||
}
|
||||
if (strpos($_GET['menuaction'],'::') !== false && strpos($_GET['menuaction'],'.') === false) // static method name app_something::method
|
||||
{
|
||||
@list($className,$functionName,$handler) = explode('::',$_GET['menuaction']);
|
||||
@ -127,5 +130,13 @@ if (isset($_GET['menuaction']))
|
||||
Json\Response::get();
|
||||
exit();
|
||||
}
|
||||
// missing menuaction GET parameter or request:parameters object or unparsable JSON
|
||||
catch (\InvalidArgumentException $e) {
|
||||
if (isset($json)) $json->isJSONRequest(false); // no regular json request processing
|
||||
|
||||
throw new Json\Exception($_SERVER['PHP_SELF'] . ' Invalid AJAX JSON Request');
|
||||
// give a proper HTTP status 400 Bad Request with some JSON payload explaining the problem
|
||||
http_response_code(400);
|
||||
header('Content-Type: application/json');
|
||||
echo json_encode(array('error' => $e->getMessage(), 'errno' => $e->getCode()));
|
||||
}
|
||||
// other exceptions are handled by our ajax_exception_handler sending them back as alerts to client-side
|
Loading…
Reference in New Issue
Block a user