How do you catch errors thrown by the HTTP client (for example a time out) so that it doesn't throw the curl error in the Laraval debugger (in debug mode) before you can do anything with the error to avoid stopping the execution?
use Illuminate\Support\Facades\Http;
try {
$request = Http::post('https://example.com/post', [
'password' => 'guest']);
} catch(ConnectException $e)
{
//log error
}
//continue with another mode
Instead, I'm always getting the Laravel's Ignition error page
Illuminate\Http\Client\ConnectionException
cURL error 28: Failed to connect to example.com port 443: Timed out
and the error is not caught by my code. Is it possible that the laravel debugger always have priority and can't be overridden in debug mode?
This is almost certainly a namespacing issue.
You'll need either this at the top of the file:
use Illuminate\Http\Client\ConnectionException;
or do this:
} catch(\Illuminate\Http\Client\ConnectionException $e)
Otherwise, you're actually trying to catch something in the current namespace named ConnectionException (i.e. something like App\Controllers\ConnectionException), which will never exist.
Related
For some reason, my Slim 4 application error handler did not catch errors which can be caught by \Exception and I see 502 bad gateway error in the browser , here is my ErrorMiddleware configuration (I'm using PHP-DI to configure it ):
$definitions[ErrorMiddleware::class] = static function(ContainerInterface $container): ErrorMiddleware {
$middleware = new ErrorMiddleware(
$container->get(CallableResolverInterface::class),
$container->get(ResponseFactoryInterface::class),
(bool)$container->get(Config::class)->get('main.debug'), //false or true
true,
true
);
$middleware->setErrorHandler(HttpNotFoundException::class, $container->get(NotFoundHandler::class));
return $middleware;
};
I tried to add handler to handle 500 error like this $middleware->setErrorHandler(HttpInternalServerErrorException::class, $container->get(NotFoundHandler::class) );
but it's not working and I still see 502 bad gateway until I surround all controller action with try/catch(\Exception $e).
Do I need to add some other error handlers?? It's not clear for me how to correctly setup up handling in a slim 4 application.
Updated: I found that slim ErrorMiddleware by default catching slim HttpException which is extending Exception, but why not direclty Exception or even Throwable to gracefully exit application with nice error page
Okay it's my bad, adn everithing is fine with a slim, it's failing in the 'log_error()' fucntion as ErrorMiddlware is configured to log the error, but I did not install and configure Monolog yet, so it write logs to php-fpm logs and nginx alongside throwing 502 error
Using monolog to log my exceptions:
try {
// php code
} catch (\Exception $e) {
$log->log(100, $e->getMessage());
}
I had problems when two parallel processes logging an error. Sometimes it worked correctly, but sometimes an error occurred saying that monolog log file “error.txt” could not be opened.
Using the native php error logging:
ini_set('error_log', "error_log.txt");
error_reporting(-1);
I had no problems so far.
Is it safe to make error logs with two parallel processes with this method ?
EDIT
$log refers to monolog Logger object:
$log = new Logger('error');
$log->pushHandler(new StreamHandler('error.txt', Logger::DEBUG));
I am working on one project that requires me to execute some commands on remote server. I am using Laravel 5.5 with package name "laravelcollective/remote" that uses SSH2 to connect with the remote server.
However, I am facing some really weird issues with some servers. I get the following error message on some of the servers.
production.ERROR: Connection closed prematurely {"exception":"[object] (ErrorException(code: 0): Connection closed prematurely at /home/username/application_name/public_html/vendor/phpseclib/phpseclib/phpseclib/Net/SSH2.php:3821, RuntimeException(code: 0): Unable to connect to remote server. at /home/username/application_name/public_html/vendor/laravelcollective/remote/src/Connection.php:143)
I am using try-catch block to catch exceptions but I am unable to catch this exception. All other Exceptions like connection timed out are being caught by the try-catch block except this one.
I am using try catch block like this:
try {
$commands = array('sudo apt-get update','sudo apt-get upgrade -y');
SSH::run($commands);
} catch (\Exception $e){
report($e);
}
But the try-catch block stops working with this connection closed prematurely error. I don't know if I am missing something or there is some bug with the library, has anyone faced the same issue before? How can I catch this error the right way?
it's because an exception is not thrown, just an error. and an error cannot be caught.
I suggest you set a global error handler that converts all the errors to exceptions, as seen in this answer here and it would be a good idea to read other answers to that question too.
Generate a custom exception handler and then in a provider or in your public/index.php set your error handler
I'm building an application with ZF2.
I use ajax to POST some data on the application and when I trhrow a new Exception with this line:
throw new \Exception("Not Loged In.", 401);
The problem is everytime I throw a new error it returns a 500 even if I put anything as a second parameter of the exception.
Can anyone help me?
Thanks!
From zend framework's request lifecycle perspective every uncaught exception is an application error. You need a mechanism to convert that exceptions to meaningful HTTP responses before the framework convert them to an HTTP 50X for you.
For example, in your controller you can try something like below:
try {
$this->myService->tryToDoSomethingThatNeedsAuthentication();
} catch(AuthRequiredException $e) {
$this->getResponse()->setStatusCode($e->getCode()) // Assuming its 401
->setReasonPhrase($e->getMessage());
return;
} catch(\Exception) {
// handle other exceptions here
}
Problem is in your php configuration. Default Apache (or other server) hide details of your internal errors, so is returned short info:
Error 500 - internal server error
You must enable error_reporting:
in PHP:
http://php.net/manual/pl/function.error-reporting.php
or in php.ini in Apache configuration, and in .htaccess file it's possible. For developer's work you should show all errors.
I use Redis as session storage in my website (Laravel 4.2). Sometimes I get following errors. I guess ">" char broke the setex commands.
production.ERROR: exception 'Predis\ServerException' with message 'ERR unknown command '>'' in
production.ERROR: exception 'Predis\ServerException' with message 'ERR unknown command 'tml>''
production.ERROR: exception 'Predis\ServerException' with message 'ERR unknown command '</div>''
These errors occurs rarely on production server and I can't reproduce them. Do you have any idea why these errors occurs and how can I prevent them?
key: laravel:xxxxxxxxxxxxxxx
value: s:217:"a:4:{s:6:"_token";s:40:"xxxxxxxxxxx";s:4:"lang";s:2:"fr";s:9:"_sf2_meta";a:3:{s:1:"u";i:1461777248;s:1:"c";i:1461777248;s:1:"l";s:1:"0";}s:5:"flash";a:2:{s:3:"old";a:0:{}s:3:"new";a:0:{}}}";
exception 'Predis\ServerException' with message 'ERR unknown command 'ml>'' in vendor/predis/predis/lib/Predis/Client.php:282
Update
Code example where I am using redis.
public function view($username = null)
{
$username = mb_strtolower($username);
$redis = $this->getRedis();
try{
$view = $redis->get(User::getCacheKeyByUsername($username));
}catch (\Exception $exception){
$view = null;
}
if($view === null || Session::has("admin")){
$user = User::where('username', '=', $username)->where("status", 1)->first();
if (empty($user)) {
return Redirect::to(Session::get("lang") . '/all');
}
$view = View::make("view", array("user" => $user));
if(!Session::has("admin")){
try{
$redis->setex(User::getCacheKeyByUsername($username), 3600, $view);
}catch (\Exception $exception){
Log::error($exception->getMessage());
}
}
}
return $view;
}
Ok, so basically what can I say from Your error log: redis doesn't like special characters like < and >, so You have to encode them.
Use htmlspecialchars to encode and htmlspecialchars_decode to decode data when retrieving.
something is wrong with your redis client. You can not reproduce it, because the error does not happen in your code, but in TCP communication between client and redis server.
i would suggest to update the question and mention what redis client module are you using. Is it predis?
If you are on unix, try compile and install phpredis. it is php module and I never had any problems with it.
Reproduction with telnet
Do telnet host port and follow instructions:
Normal request GET a would look like this:
*2
$3
get
$1
a
$-1
Now consider this - ask for gem a:
*2
$3
gem
$1
a
-ERR unknown command 'gem'
Protocol is valid, but command "gem" is invalid.
Now consider this:
*1
$3
ml>
-ERR unknown command 'ml>'
Here is your error. Valid protocol, invalid command.
Alternatively consider this:
*2
$3
get
$1
<html>
$-1
-ERR unknown command 'ml>'
Here is your error again. Invalid strlen("<html>");
Why this is redis client error and not user error:
Many redis clients uses PHP magic methods.
This means if you call $redis->bla(), they extract "bla" part and it parameters and forward them to the redis server.
However you can not do $redis->ml>(). This will be syntax error. So this is error from redis client, not from your code.
It also looks like part of HTML. It looks like you are storing HTML data in redis. I only can guess that the client does not compute strlen() or count() and send wrong information "down the telnet line".