/** * Raise an xmlrpc server fault * * Moodle note: the difference with the Zend server is that we throw a plain PHP Exception * with the debuginfo integrated to the exception message when DEBUG >= NORMAL * * @param string|Exception $fault * @param int $code * @return Zend_XmlRpc_Server_Fault */ public function fault($fault = null, $code = 404) { //intercept any exceptions with debug info and transform it in Moodle exception if ($fault instanceof Exception) { //add the debuginfo to the exception message if debuginfo must be returned if (debugging() and isset($fault->debuginfo)) { $fault = new Exception($fault->getMessage() . ' | DEBUG INFO: ' . $fault->debuginfo, 0); } } return parent::fault($fault, $code); }
/** * fault() test */ public function testFault() { $fault = $this->_server->fault('This is a fault', 411); $this->assertTrue($fault instanceof Zend_XmlRpc_Server_Fault); $this->assertEquals(411, $fault->getCode()); $this->assertEquals('This is a fault', $fault->getMessage()); $fault = $this->_server->fault(new Zend_XmlRpc_Server_Exception('Exception fault', 511)); $this->assertTrue($fault instanceof Zend_XmlRpc_Server_Fault); $this->assertEquals(511, $fault->getCode()); $this->assertEquals('Exception fault', $fault->getMessage()); }
/** * Multicall - boxcar feature of XML-RPC for calling multiple methods * in a single request. * * Expects a an array of structs representing method calls, each element * having the keys: * - methodName * - params * * Returns an array of responses, one for each method called, with the value * returned by the method. If an error occurs for a given method, returns a * struct with a fault response. * * @see http://www.xmlrpc.com/discuss/msgReader$1208 * @param array $methods * @return array */ public function multicall($methods) { $responses = array(); foreach ($methods as $method) { $fault = false; if (!is_array($method)) { $fault = $this->_server->fault('system.multicall expects each method to be a struct', 601); } elseif (!isset($method['methodName'])) { $fault = $this->_server->fault('Missing methodName: ' . var_export($methods, 1), 602); } elseif (!isset($method['params'])) { $fault = $this->_server->fault('Missing params', 603); } elseif (!is_array($method['params'])) { $fault = $this->_server->fault('Params must be an array', 604); } else { if ('system.multicall' == $method['methodName']) { // don't allow recursive calls to multicall $fault = $this->_server->fault('Recursive system.multicall forbidden', 605); } } if (!$fault) { try { $request = new Zend_XmlRpc_Request(); $request->setMethod($method['methodName']); $request->setParams($method['params']); $response = $this->_server->handle($request); if ($response instanceof Zend_XmlRpc_Fault || $response->isFault() ) { $fault = $response; } else { $responses[] = $response->getReturnValue(); } } catch (Exception $e) { $fault = $this->_server->fault($e); } } if ($fault) { $responses[] = array( 'faultCode' => $fault->getCode(), 'faultString' => $fault->getMessage() ); } } return $responses; }
/** * Generate a server fault * * Note that the arguments are reverse to those of Zend_XmlRpc_Server_Fault. * * note: the difference with the Zend server is that we throw a Zend_XmlRpc_Server_Fault exception * with the debuginfo integrated to the exception message when DEBUG >= NORMAL * * If an exception is passed as the first argument, its message and code * will be used to create the fault object if it has been registered via * {@Link registerFaultException()}. * * @param string|Exception $fault * @param string $code XMLRPC Fault Codes * @return Zend_XmlRpc_Server_Fault */ public function fault($fault = null, $code = 404) { //run the zend code that clean/create a xmlrpcfault $xmlrpcfault = parent::fault($fault, $code); //intercept any exceptions and add the errorcode and debuginfo (optional) $actor = null; $details = null; if ($fault instanceof Exception) { //add the debuginfo to the exception message if debuginfo must be returned if (ws_debugging() and isset($fault->debuginfo)) { $details = $fault->debuginfo; } } $fault = new Zend_XmlRpc_Server_Fault($xmlrpcfault); $fault->setCode($xmlrpcfault->getCode()); $fault->setMessage($xmlrpcfault->getMessage() . ' | ERRORCODE: ' . $xmlrpcfault->getCode() . ' | DETAILS: ' . $details); return $fault; }
/** * Raise an xmlrpc server fault * * Moodle note: the difference with the Zend server is that we throw a plain PHP Exception * with the debuginfo integrated to the exception message when DEBUG >= NORMAL * * @param string|Exception $fault * @param int $code * @return Zend_XmlRpc_Server_Fault */ public function fault($fault = null, $code = 404) { // Intercept any exceptions with debug info and transform it in Moodle exception. if ($fault instanceof Exception) { // Code php exception must be a long // we obtain a hash of the errorcode, and then to get an integer hash. $code = base_convert(md5($fault->errorcode), 16, 10); // Code php exception being a long, it has a maximum number of digits. // we strip the $code to 8 digits, and hope for no error code collisions. // Collisions should be pretty rare, and if needed the client can retrieve // the accurate errorcode from the last | in the exception message. $code = substr($code, 0, 8); // Add the debuginfo to the exception message if debuginfo must be returned. if (debugging() and isset($fault->debuginfo)) { $fault = new Exception($fault->getMessage() . ' | DEBUG INFO: ' . $fault->debuginfo . ' | ERRORCODE: ' . $fault->errorcode, $code); } else { $fault = new Exception($fault->getMessage() . ' | ERRORCODE: ' . $fault->errorcode, $code); } } return parent::fault($fault, $code); }
public function testCreatingFaultWithEmptyMessageResultsInUnknownError() { $fault = $this->_server->fault('', 123); $this->assertSame('Unknown Error', $fault->getMessage()); $this->assertSame(123, $fault->getCode()); }