So I have this code and I'm trying to catch an error when I can't connect for some reason (wrong credentials or no network connection or something similar), but it is not working and my app crashes with error.
try {
$connection = new Remote([
'host' => $equipment->ip_address,
'port' => 22,
'username' => EquipmentAccess::where('equipment_id', $equipment->id)->first()->ssh_user,
'password' => EquipmentAccess::where('equipment_id', $equipment->id)->first()->ssh_password,
]);
$command = $request->command . ' ' . $request->argv;
$ip = $connection->exec($command);
} catch (Exception $e) {
echo "Houston, we have a problem:" . $e;
}
If anyone can give me any information about what I missed, it will be highly appreciated.
EDIT: I guess, I wasn't clear enough. It crashes with typical laravel pipeline error and the latest is, that it can't connect to that device. And it should just give me my error message.
EDIT2: here is a link to a SS of the stack-trace - https://gyazo.com/9095d5600be2b7f07ca59d93624f9187
Related
I am building a simple REST API package using cURL and would like to catch an error and then return a view. I am able to throw an error if I dd($e) but if I try and return a view it just continues with the code after the catch function. Shouldn't PHP kill the process and just go to the login view?
try{
$response = Http::timeout(2)->asForm()->post('https://' . $this->ip_address, [
'username' => $this->username,
'password' => $this->password
]);
} catch(\Illuminate\Http\Client\ConnectionException $e) {
return view('auth.login');
}
If I get a cURL timeout exception I just want to go back to the login page for now. If I put in a bogus IP address obviously it will timeout after 2 seconds, which is what I am testing.
Using Laravel Http client, how can I catch that error and display the auth login view?
Unlike Guzzle, Laravel's HttpClient does not throw errors if the response is > 400.
You should simply use an if statement to check the response status code. See: https://laravel.com/docs/8.x/http-client#error-handling
You can call use the following checks:
// Determine if the status code is >= 200 and < 300...
$response->successful();
// Determine if the status code is >= 400...
$response->failed();
// Determine if the response has a 400 level status code...
$response->clientError();
// Determine if the response has a 500 level status code...
$response->serverError();
So in your case you can simply do something like this:
$response = Http::timeout(2)->asForm()->post('https://' . $this->ip_address, [
'username' => $this->username,
'password' => $this->password
]);
if ($response->failed()) {
return view('your-view')->with([
'message' => 'Failed.',
]);
}
Could you try this please?
try {
$response = Http::timeout(2)->asForm()->post('https://' . $this->ip_address, [
'username' => $this->username,
'password' => $this->password
]);
} catch(\Illuminate\Http\Client\ConnectionException $e) {
return view('auth.login')->with('errorMessage', $e->getMessage());
}
And you can show the error on the frontend, like below;
#if(!empty($errorMessage))
<div class="alert alert-danger"> {{ $errorMessage }}</div>
#endif
It is better if you change your approach in using Laravel's HTTP client,
Move time-intensive tasks - like Http requests - to a job, and run that job in a background queue.
Then, for example, if you wanna use that Http request for authentication, handle your auth logic on that job, don't forget to log and handle exceptions.
afterward, protect your private routes using middlewares and make redirect unauthenticated users to your login page in that middleware.
I hope I could be clear
I am developing a Web application. In my app, I need to login user to the AWS cognito system. I can log in to the system successfully. But the only problem is when the username and password provided by the user are not valid, my Laravel framework kills the application returning 500 internal server status code. But I want to do something else when the username and password are not valid. I tried using try catch block, but it is not overriding the error. Please, see my code below.
try{
$client = new CognitoIdentityProviderClient([
'version' => 'latest',
'region' => env('AWS_REGION', '')
'credentials' => [
'key' => env('AWS_IAM_KEY', ''),
'secret' => env('AWS_IAM_SECRET', '')
]
]);
$result = $client->adminInitiateAuth([
'AuthFlow' => 'ADMIN_NO_SRP_AUTH',
'ClientId' => COGNITO_APP_CLIENT_ID,
'UserPoolId' => COGNITO_USER_POOL_ID,
'AuthParameters' => [
'USERNAME' => $request->email,
'PASSWORD' => $request->password,
],
]);
//Error thrown here if the username and password are not valid.
//continue
}
catch(Exception $e)
{
//I want to do something here if the error is thrown because of the invalid credentials without killing the app by throwing 500 status code.
}
As you can see in the above code if the user credentials are not valid, the SDK will throw the error. It will kill the app by returning 500 status code. I do not want to stop there. So, I used the try catch block to catch the error and continue in the code. But the try catch block is not catching the error as well.
This is the screenshot.
So, how can I stop the AWS sdk from stopping the application throwing 500 status code?
Finally, I found the solution. Laravel works with namespaces. So, instead of using just Exception in the try catch block, I needed to put "\" as a prefix. So the try catch becomes like this.
try{
//code
}
catch(\Exception $e) //pay attention to the "\"
{
}
I am using Laravel 5.5 with the AWS SDK for laravel (https://github.com/aws/aws-sdk-php-laravel).
I'm trying to do a simple request to establish that I'm connecting correctly. I believe I have my credentials all set and nothing points to that as an error.
Here is the function in my laravel controller that is being called:
public function testData(Request $request) {
$sdk = new Sdk([
'endpoint' => 'http://localhost:80',
'region' => 'us-east-1',
'version' => 'latest'
]);
$dynamodb = $sdk->createDynamoDb();
$marshaler = new Marshaler();
$tableName = 'funTalkDataStorage';
$params = [
'TableName' => $tableName
];
try {
$result = $dynamodb->query($params);
} catch (DynamoDbException $e) {
echo "Unable to query:\n";
echo $e->getMessage() . "\n";
}
}
The table 'funTalkDataStorage' does exist out on AWS already where there are two records already.
The thing that I'm not understanding is why I'm getting the following error from Laravel:
Aws \ Api \ Parser \ Exception \ ParserException
Error parsing JSON: Syntax error
being thrown by :
aws\aws-sdk-php\src\Api\Parser\PayloadParserTrait.php
The error is originating from the line in my code:
$result = $dynamodb->query($params);
I've been digging through the sdk and searching the web and I'm just not getting where the issue is. Any help would be marvalous!
Ok. My issue was that i was using port 80. It should have been port 8000.
I'm having an issue where my php function works when I call it from the server's command line, but not on the web page. It also works on the web page when I have it hosted locally through WAMP.
Any ideas what might be the issue?
function getCFTemplateSummary($CFUrl){
//init client
$client = new CloudFormationClient(array(
'profile' => 'default',
'region' => 'us-east-1',
'version' => '2010-05-15',
'http' => [ 'verify' => false ]
));
try {
$result = $client->getTemplateSummary(['TemplateURL' => $CFUrl]);
}catch(\Aws\CloudFormation\Exception\CloudFormationException $e){
echo $e->getMessage();
}catch(\Aws\Exception\AwsException $e){
echo $e->getMessage();
}
echo "<pre>";
print_r($result);
echo "inside the function";
echo "</pre>";
return $result;
}
I was able to trace down the issue to this by trial and error commenting ...but not sure how to proceed debugging as I don't see any error messages.
$result = $client->getTemplateSummary(['TemplateURL' => $CFUrl]);
Try catching Exception instead of \Aws\CloudFormation\CloudFormationException, it's possible that a different Exception (e.g., incorrectly configured AWS credentials) is being thrown from your server that you aren't explicitly catching in your current code.
Hi I have a php daemon that handle request from rabbitmq
After a day, it can no longer execute due to error MySQL has gone away.
PHP Warning: PDOStatement::execute(): MySQL server has gone away in /var/www/daemon/www/vendor/zendframework/zendframework/library/Zend/Db/Adapter/Driver/Pdo/Statement.php on line 239
PHP Warning: PDOStatement::execute(): Error reading result set\'s header in /var/www/daemon/www/vendor/zendframework/zendframework/library/Zend/Db/Adapter/Driver/Pdo/Statement.php on line 239
I didn't use doctrine, instead I send my \Zend\Db\Adapter\Adapter to a db wrapper class with below function.
public static function executeScalar($statement, $parameters, \Zend\Db\Adapter\Adapter $dbAdapter)
{
$dbResult = new DbResult();
if (! $statement) {
$dbResult->addError('No statement given');
return $dbResult;
}
$stmt = $dbAdapter->createStatement();
$stmt->prepare($statement);
foreach ($parameters as $key => &$param) {
$stmt->getResource()->bindParam($key + 1, $param[0], $param[1]);
}
try {
$result = $stmt->execute();
$dbResult->setResult($result);
} catch (\Zend\Db\Adapter\ExceptionInterface $e) {
$dbResult->addError('DB Error');
$message = $e->getPrevious() ? $e->getPrevious()->getMessage() : $e->getMessage();
$dbResult->addError($message);
} catch (\Zend\Db\Adapter\Exception $e) {
$dbResult->addError('DB Error');
$dbResult->addError($e->getMessage());
} catch (\PDOException $e) {
$dbResult->addError('DB Error');
$dbResult->addError($e->getMessage());
} catch (\Exception $e) {
$dbResult->addError('DB Error');
$dbResult->addError($e->getMessage());
}
$stmt->getResource()->closeCursor();
return $dbResult;
}
DbResult is my own db result wrapper class it mainly check whether it return empty, what's the error, how many rows, etc.
Here is my database.local.php configuration
return array(
'service_manager' => array(
'factories' => array(
'mysql' => function ($sm)
{
return new Zend\Db\Adapter\Adapter(array(
'driver' => 'PdoMysql',
'hostname' => 'localhost',
'database' => 'daemon',
'username' => 'daemon',
'password' => 'password',
'driver_options' => array(
\PDO::MYSQL_ATTR_INIT_COMMAND => 'SET NAMES \'UTF8\'',
\PDO::ATTR_ERRMODE => \PDO::ERRMODE_EXCEPTION,
\PDO::ATTR_EMULATE_PREPARES => true,
\PDO::MYSQL_ATTR_LOCAL_INFILE => true
)
));
},
)
)
)
So everytime I want to execute a sql I do this inside controller or any other class ( Just an example )
$service = $this->getServiceLocator();
$dbAdapter = $service->get('mysql');
$get = \Db\Database::executeScalar('SELECT * FROM mytable WHERE id <= ?', array(10), $dbAdapter);
It seems I cannot catch the warning, and is there a way to force reconnect or perhaps I just do a disconnect after each request ?
Will this works, to handle the error ?
On every new request I do this
$dbAdapter->getDriver()->getConnection()->connect();
At the end of request I do this
$dbAdapter->getDriver()->getConnection()->disconnect();
Yes, I check the persistent connection option, but I also not fond of it.
I find the problem, it cause by mysql server close idle connection after 'wait timeout'. when mysql closing the idle connection, PDO will not receive any event so the next time you initiate a query it will return Mysql has gone away error.
For http request this is acceptable since after the server response the request it will stop/exit php execution which close all connection to database.
For daemon/service this is not acceptable since most of the time it waiting for client request (idle). My solution is to close the connection everytime it finish handling client request. e.g :
while (true) {
//listen to rabbitmq queue
//...
//do something base on client request from rabbitmq queue
//...
//close the connection whether it use database or not
//connection will be reconnected when we call $service->get('mysql');
$service = $this->getServiceLocator();
$dbAdapter = $service->get('mysql');
$dbAdapter->getDriver()->getConnection()->disconnect();
}
You can create a persistent connection to your database but be warned that creating a persistent connection should not be the first solution to look for. Be sure to do some research on the subject before trying it. You can find some documentation here :
http://php.net/manual/en/pdo.connections.php#example-954
On the other hand, you should look for the queries sent so the reason of the gone away message is not caused by the mysql server recieving a packet too large (ex: inserting a large blob). Because if it is, the connection will still close unexpectedly.