I'm following a tutorial on how to use the Google Reseller API. I've come to the section on determining whether a customer already exists in Google Apps (Step 2) but have come unstuck in handling the Google_Service_Exception object.
If a customer doesn't exist then a call to the API will return a 404 error. I'm using the code property of the Google_Service_Exception object $e to determine if the response has a 404 error. However when I try to return the error code with $e->code with:
try {
// Call to the Google Reseller API
} catch (Google_Service_Exception $e) {
if($e->code == 404){
return false;
}
}
I get the following PHP error:
Fatal error: Cannot access protected property Google_Service_Exception::$code.
The Google_Service_Exception class is as follows:
<?php
require_once 'Google/Exception.php';
class Google_Service_Exception extends Google_Exception
{
/**
* Optional list of errors returned in a JSON body of an HTTP error response.
*/
protected $errors = array();
/**
* Override default constructor to add ability to set $errors.
*
* #param string $message
* #param int $code
* #param Exception|null $previous
* #param [{string, string}] errors List of errors returned in an HTTP
* response. Defaults to [].
*/
public function __construct(
$message,
$code = 0,
Exception $previous = null,
$errors = array()
) {
if (version_compare(PHP_VERSION, '5.3.0') >= 0) {
parent::__construct($message, $code, $previous);
} else {
parent::__construct($message, $code);
}
$this->errors = $errors;
}
/**
* An example of the possible errors returned.
*
* {
* "domain": "global",
* "reason": "authError",
* "message": "Invalid Credentials",
* "locationType": "header",
* "location": "Authorization",
* }
*
* #return [{string, string}] List of errors return in an HTTP response or [].
*/
public function getErrors()
{
return $this->errors;
}
}
So I assumed the error has something to do with the fact that $errors is protected. I imagine it is protected for a reason so I was a bit wary of changing the class. Any help / pointers in working around this error would be greatly appreciated. Thanks
Just use the getCode() method:
try {
// Call to the Google Reseller API
} catch (Google_Service_Exception $e) {
if($e->getCode() == 404){ // <- Change is here
return false;
}
}
Google_Service_Exception extends Google_Exception and Google_Exception extends Exception. You may read the documentation about Exception here. You will see the getCode method.
Related
The drupal/simple_oauth module creates an oauth2_token table. This table has a column value and I've examined the source code but I cannot work out how this value is generated.
To make this a little bit more complicated, I don't have this service running locally, and I don't have access to the remote server it is running on, I only have access to the database itself.
I am creating a Python service that is using the Drupal database (because reasons). I am able to generate all the required data except this value field.
I can copy the value field from one of the existing access tokens, and use it in a new record I create via a SQL INSERT. The JWT I create from this record's value works correctly with the protected endpoint. However, if I set an arbitrary value like a UUID, the request to the protected resource fails with the following error response:
{
"error": "permission_denied",
"error_description": "The 'debug simple_oauth tokens' permission is required.",
"status_code": 403,
"detail": "permission_denied"
}
The value is used in the jti of the JWT and I can see in src/Entities/AccessTokenEntity.php that this is set to $this->getIdentifier(); (<-- comments are mine):
public function convertToJWT() {
$private_claims = [];
\Drupal::moduleHandler()
->alter('simple_oauth_private_claims', $private_claims, $this);
if (!is_array($private_claims)) {
$message = 'An implementation of hook_simple_oauth_private_claims_alter ';
$message .= 'returns an invalid $private_claims value. $private_claims ';
$message .= 'must be an array.';
throw new \InvalidArgumentException($message);
}
$id = $this->getIdentifier(); /* <-- NOTE */
$now = new \DateTimeImmutable('#' . \Drupal::time()->getCurrentTime());
$key_path = $this->privateKey->getKeyPath();
$key = InMemory::file($key_path);
$config = Configuration::forSymmetricSigner(new Sha256(), $key);
$builder = $config->builder()
->permittedFor($this->getClient()->getIdentifier())
->identifiedBy($id) /* <-- SET THE JTI */
->withHeader('jti', $id)
->issuedAt($now)
->canOnlyBeUsedAfter($now)
->expiresAt($this->getExpiryDateTime())
->relatedTo($this->getUserIdentifier())
->withClaim('scope', $this->getScopes());
And this is where my investigation has stopped, as I cannot work out where getIdentifier() is implemented.
I cross-posted this question to Drupal Answers and #apaderno noted this wasn't a Drupal specific question, which nudged me towards the source for The source for PHP OAuth 2.0 Server.
The source of the value column is the generateUniqueIdentifier function in AbstractGrant.php:
/**
* Generate a new unique identifier.
*
* #param int $length
*
* #throws OAuthServerException
*
* #return string
*/
protected function generateUniqueIdentifier($length = 40)
{
try {
return \bin2hex(\random_bytes($length));
// #codeCoverageIgnoreStart
} catch (TypeError $e) {
throw OAuthServerException::serverError('An unexpected error has occurred', $e);
} catch (Error $e) {
throw OAuthServerException::serverError('An unexpected error has occurred', $e);
} catch (Exception $e) {
// If you get this message, the CSPRNG failed hard.
throw OAuthServerException::serverError('Could not generate a random string', $e);
}
// #codeCoverageIgnoreEnd
}
I getting this is exception in my application, and don't understand why. This exception throw in for one collection, over collection not throw this exception, with processed insert(),update(), or delete()
/**
* insert to mongo db method
* #param $dataArray
* #param $collection
*/
static function insert($dataArray, $collection) {
$connect = Core_Model_Mongo::getConnect();
$write = new MongoDB\Driver\BulkWrite();
$writeConcern = new MongoDB\Driver\WriteConcern(MongoDB\Driver\WriteConcern::MAJORITY);
$write->insert($dataArray);
$connect->executeBulkWrite(
Config_Db::getConf()['mongodb']['db'].'.'.$collection,
$write,
$writeConcern
);
}
end get connect method
/**
* #return \MongoDB\Driver\Manager
*/
static function getConnect() {
if(!is_null(self::$_connect)) {
return self::$_connect;
}
self::$_connect = new \MongoDB\Driver\Manager(Config_Db::getConf()['mongodb']['connect']);
return self::$_connect;
}
data save in collection success full, and this exception not take insert(),update() and other methods. I temporary resolve this question by try catch block
try {
// my code
} catch(MongoDB\Driver\Exception\BulkWriteException $error) {
Core_App::log(var_export($error,true));
}
but this is resolve not correct because I need application without any exception,error,notice, and over log level error.
Am getting Integrity constraint violation – yii\db\IntegrityException Error when am delete a row without deleting a row in foreign key table.
How i can show custom Error Page instead of Integrity constraint violation – yii\db\IntegrityException Error in Yii 2
How i can catch and throw exception for this in Yii 2.0
This will not actually the answer you have asked but I have customized error handler in Yii1, and hope it have same behavior in Yii2. You can change it on config/main.php as:
'errorHandler' => [
'errorAction' => 'site/error' // To error/errorHandler
],
And the Controller Class error have the following lines. You can change it on your need.
class ErrorController extends CController {
public $layout = '//layouts/column1';
/**
* This is the action to handle external exceptions.
*/
public function actionErrorHandler() {
if ($error = Yii::app()->errorHandler->error) {
if ('CDbException' != $error['type']) {
if (Yii::app()->request->isAjaxRequest)
echo $error['message'];
else
$this->commonError($error);
}else if ('CDbException' == $error['type']) {
if (Yii::app()->request->isAjaxRequest)
echo $error['message'] = 'The system is unable to resolve the database error !';
else
$this->databaseError($error);
}
}
}
/**
*
* #param type array $error
* #access : Internal, type private
* #throws: Http exception.
*/
private function commonError($error) {
$this->render('code_error', $error);
}
/**
*
* #param type array $error
* #throws Exception
*/
private function databaseError($error) {
if (empty($error)) {
$error['code'] = '404';
$error['message'] = 'Unknown error !';
$this->render('code_error', $error);
Yii::app()->end(0, true);
}
$error['message'] = 'The system is unable to resolve the database error !';
$this->render('database_error', $error);
}
}
Should I check if a key exists and then get it or just get it (when I need to get it, not check if its set)?
What is more reliable? safer? faster?
Examples:
1) PHP redis (https://github.com/nicolasff/phpredis)
if ($redis->exists('key'))
echo $redis->get('key');
// VS
if ($value = $redis->get('key'))
echo $value;
2) PHP phalcon cookies(http://docs.phalconphp.com/pt/latest/reference/cookies.html)
if ($this->cookies->has('remember-me'))
echo $this->cookies->get('remember-me')->getValue()
// VS
if ($value = $this->cookies->get('remember-me')->getValue())
echo $value;
Thank you!
My interpretation of this problem is:
I don't like writing things like
if ($value = $redis->get('key'))
echo $value;
it makes code unclear.
Also, why is checking if variable exists so important? Because it simplifies control flow.
Let's consider that you're grabbing some data from service to render it on page. You can write low quality code with multiple ifs, but you can also try something like this:
offerServiceImpl.php
class offerServiceImpl implements offerService {
//... (some methods)
/**
* #param int $offerId
* #return Offer
* #throws InvalidArgumentException
* #throws RuntimeException
*/
public function getOffer($offerId)
{
if (!$offerId || !is_numeric($offerId)) {
throw new InvalidArgumentException("Invalid offer id: " . $offerId);
}
$offer = $this->offerDao->get($offerId);
if (!$offer) {
//could be your own exception class
throw new RuntimeException("Could not found offer " . $offerId);
} else {
return $offer;
}
}
}
offersControler.php
class offersController extends AbstractController{
public function index($id){
//... some code
try{
$offer = $this->offerService->getOffer($id);
} catch (InvalidArgumentException $ex) {
//log error, perform redirect to error 500
} catch (RuntimeException $ex){
//log another error, perform redirect to error 404
} catch (Exception $ex){
//log error, perform redirect to error 500
}
}
}
I am new to Zend Framework. I am working on an app to search through Gmail inbox by using the class (which I added to Zend/Mail/Storage/Imap.php)
/**
* do a search request
*
* This method is currently marked as internal as the API might change and is not
* safe if you don't take precautions.
*
* #internal
* #return array message ids
*/
public function search(array $params)
{
$response = $this->requestAndResponse('SEARCH', $params);
if (!$response) {
return $response;
}
foreach ($response as $ids) {
if ($ids[0] == 'SEARCH') {
array_shift($ids);
return $ids;
}
}
return array();
}
And I am calling it like this:
$searchresults = $storage->search(array('search_terms'));
But everytime I try to run it, it shows an error:
PHP Fatal error: Call to undefined method Zend_Mail_Storage_Imap::requestAndResponse() in /public_html/test06/Zend/Mail/Storage/Imap.php on line 655
It seems that requestAndResponse is not defined in the way you're calling it. I don't use ZF, but are you sure requestAndResponse accepts the 2 param you're sending. I mean ('SEARCH', $params).