I have a small slim 3 app, and when I throw an exception slim simply shows the generic error message:
Slim Application Error
A website error has occurred. Sorry for the temporary inconvenience.
In slim 2 you can do something like this to turn on debug mode giving you backtraces etc:
$app->config('debug', true);
In slim 3 there doesn't seem to be one. Additionally, it seems to be overriding my exception and error handlers.
How can I get slim to spit out errors, or at least to call my error handlers (Which pipe the output to kint for debug information)
Looking through the source, it's possible to initialize slim 3 with error display like so:
$app = new \Slim\App(['settings' => ['displayErrorDetails' => true]]);
I'm not sure if it's possible to change this setting after the fact without replacing the errorHandler altogether.
To show full stack trace on default exception handler use what j-v said.
If you want to handle exceptions in Slim yourself then you need to override Slim's default exception handler as it will be used before your "not in Slim" error handler:
$app = new \Slim\App();
$container = $app->getContainer();
$container['errorHandler'] = function(ServerRequestInterface $request, ResponseInterface $response, Exception $exception) {
//Handle exception here
}
Error handling is rather well documented: Official Docs
$app = new \Slim\App();
$c = $app->getContainer();
$c['errorHandler'] = function ($c) {
return function ($request, $response, $exception) use ($c) {
return $c['response']->withStatus(500)
->withHeader('Content-Type', 'text/html')
->write('Something went wrong!');
};
};
Error handling is best solution to this. You can do something like to see Error Trace
$app = new \Slim\App();
$container = $app->getContainer();
$container['phpErrorHandler'] = $container['errorHandler'] = function ($c) {
return function ($request, $response, $exception) use ($c) {
return $c['response']->withStatus(500)
->withHeader('Content-Type', 'text/html')
->write('Something went wrong!<br><br>' .
nl2br($error->getTraceAsString()));
};
};
Make displayErrorDetails->true.
You will find cause of error.
$config = ['settings' => [
'addContentLengthHeader' => true,
'displayErrorDetails' => true
]];
$app = new \Slim\App($config)
Related
I am using slim framework 3 . I am new to this framework. I am working on catching the errors and returning the custom JSON error and message.
I used this code to catch notFoundHandler error :
$container['notFoundHandler'] = function ($c) {
return function ($request, $response) use ($c) {
return $c['response']
->withStatus(404)
->withHeader('Content-Type', 'application/json')
->write('Page not found');
};
};
But I am able to catch the normal syntax error.
It is showing Warning: fwrite() expects parameter 2 to be string, array given in X-api\controllers\Products.php on line 42
Instead of this message, I want my custom error to handle syntax error reporting.
I used this also,
$container['phpErrorHandler'] = function ($c) {
return function ($request, $response, $exception) use ($c) {
//Format of exception to return
$data = [
'message' => "hello"
];
return $container->get('response')->withStatus($response->getStatus())
->withHeader('Content-Type', 'application/json')
->write(json_encode($data));
};
};
But not working for me.
The default error handler can also include detailed error diagnostic information. To enable this you need to set the displayErrorDetails setting to true:
$configuration = [
'settings' => [
'displayErrorDetails' => true,
],
];
$c = new \Slim\Container($configuration);
$app = new \Slim\App($c);
Note this is not appropriate for production applications, since it may reveal some details you would want not to reveal. You can find more in Slim docs.
EDIT
If you need to handle parseErrors, then you need to define phpErrorHandler in your container, just like you did define notFoundHandler.
$container['phpErrorHandler'] = function ($container) {
return function ($request, $response, $error) use ($container) {
return $container['response']
->withStatus(500)
->withHeader('Content-Type', 'text/html')
->write('Something went wrong!');
};
};
Note: this will work with PHP7+ only, because in older versions parseErrors cannot be catched.
I have used this short of code in my dependencies.php
$container['errorHandler'] = function ($c) {
return function ($request, $response) use ($c) {
$data = [
'message' => "Syntex error"
];
return $c['response']
->withStatus(200)
->withHeader('Content-Type', 'application/json')
->write(json_encode($data));
};
};
set_error_handler(function ($severity, $message, $file, $line) {
if (!(error_reporting() & $severity)) {
// This error code is not included in error_reporting, so ignore it
return;
}
throw new \ErrorException($message, 0, $severity, $file, $line);
});
Now its working for me.
I'am working on a Zend Framework 2 application and have a strange behavior concerning error handling. My code in Module.php:
public function onBootstrap(MvcEvent $e)
{
$eventManager = $e->getApplication()->getEventManager();
$moduleRouteListener = new ModuleRouteListener();
$moduleRouteListener->attach($eventManager);
$eventManager->attach(\Zend\Mvc\MvcEvent::EVENT_ROUTE, [$this, 'onPreRoute'], 100);
$eventManager->attach(\Zend\Mvc\MvcEvent::EVENT_DISPATCH_ERROR, [$this, 'handleError']);
}
public function onPreRoute(MvcEvent $e)
{
$serviceManager = $e->getTarget()->getServiceManager();
$router = $serviceManager->get('router');
$router->setTranslator($serviceManager->get('translator'));
}
public function handleError(MvcEvent $e)
{
$error = $e->getParam('error');
file_put_contents('error.log', $error . PHP_EOL, FILE_APPEND);
switch($error) {
case 'error-router-no-match':
$router = $e->getRouter();
$url = $router->assemble([], ['name' => 'home']);
header('Location: ' . $url);
exit;
}
}
As you can see I'am translating the routes. This works fine. But on every request the dispatch error event is triggered too. The error.log file will be created every time. But the redirect will be only performed if the route doesn't really exist. I think it depends on the translator or is my code in Module.php not correct?
Resolved!
The reason was that the browser automatically requests /favicon.ico and that was not available :-)
Creating an App in Silex and trying to take the first few steps, one of which is setting up my services/providers.
I am currently loading these using a YAML file. I have also tried registering each individual like the docs say e.g.
$this->register( new TwigServiceProvider(),array() );
Here is my current bootstrap file(loading services from a file):
<?php
namespace App;
use Igorw\Silex\ConfigServiceProvider;
use Silex\Application as Silex;
use Symfony\Component\Routing\Route;
use Symfony\Component\Routing\RouteCollection;
use Symfony\Component\HttpFoundation\Request;
class Bootstrap extends Silex
{
public function __construct()
{
$this['debug'] = true;
$this->registerDefaultParameters();
$this->registerDefaultServices();
$this->registerRoutes();
}
protected function registerDefaultParameters()
{
$paths = isset($this['base_path']) ? $this['base_path'] : array();
if (!isset($paths['base'])) {
$paths['base'] = realpath(__DIR__ . '/../');
}
$defaults = array(
'config' => $paths['base'] . '/App/Config',
'twig.path' => $paths['base'] . '/public/themes/base/templates'
);
foreach ($defaults as $key => $value) {
if (!isset($paths[$key])) {
$paths[$key] = $value;
}
}
$this['paths'] = $paths;
}
protected function registerDefaultServices()
{
$this->register( new ConfigServiceProvider($this['paths']['config'] . "/Services.yml") );
foreach($this['services'] as $serviceName => $serviceData)
{
$this->register( new $serviceData['class'],(array_key_exists('parameters',$serviceData)) ? $serviceData['parameters'] : array() );
}
}
protected function registerRoutes()
{
$this->register( new ConfigServiceProvider($this['paths']['config'] . "/Routes.yml") );
$collection = new RouteCollection();
foreach($this['routes'] as $key => $value)
{
$collection->add( $key, new Route(
$value['path'],
$value['defaults'],
array(),
array(),
null,
null,
$value['methods']
));
}
$this['routes'] = $collection;
}
}
My issue is:
With every provider i am receiving fatal errors like
Fatal error: Uncaught exception 'InvalidArgumentException' with message 'Identifier "this_is_an_identifier" is not defined.'
I'm receiving this errors loading the services from a file and manually. and its different for each provider e.g.
The error related to the twig provider is:
Fatal error: Uncaught exception 'InvalidArgumentException' with message 'Identifier "request_error" is not defined.'
Another one relating to Monolog is :
Fatal error: Uncaught exception 'InvalidArgumentException' with message 'Identifier "dispatcher" is not defined.
So its like every provider/service has something wrong which obviously isn't the case. So my question is why am i continuously receiving these errors? from what i can see im not doing anything wrong?
Heres my composer file just in case it's a version thing:
{
"name": "cranbri/cvcms",
"description": "Cranbri CV CMS Silex",
"minimum-stability": "dev",
"require": {
"silex/silex": "1.2.2",
"symfony/yaml": "2.6.1",
"igorw/config-service-provider": "1.2.2"
},
"autoload": {
"psr-4":{
"App\\": "App/"
}
}
}
This is stopping my development altogether so if anyone can give me any details it will be much appreciated. Cheers
I wasn't calling parent!!! therefore i have none of the values the parent class did hence why many of the $app variables were not set and couldn't be found
I'm trying to set up a hook to catch all exceptions and errors thrown from my Dancer application ( an API ) and pass them to a function that sets the HTTP status code and returns the hash ( serialized as JSON ).
Everything works fine when I use try/catch, but when I move it to a hook it runs the code but the response is formed using the default error mechanism instead of my function.
This is the hook I'm using:
# Handle errors
hook on_handler_exception => sub {
my $e = shift;
debug "ON HANDLER EXCEPTION";
return API::Exception->handle($e); # sets status code and returns hash depending on the exception
};
I also tried using halt instead of return to stop any further processing of the exception but it didn't alter anything.
How would I accomplish this with Dancer? Thanks.
use the "on_route_exception" hook instead ...
hook on_route_exception => sub
{
my ( $exception ) = #_;
error( $exception );
status( 'error' );
halt( { errors => [ { message => 'An unhandled exception occurred', code => 0 } ] } );
};
Have a look at the code of Dancer::Error.
I think something like
my $content = Dancer::Engine->engine("template")->apply_renderer($template_name, $ops);
return Dancer::Response->new(
status => $self->code,
headers => ['Content-Type' => 'text/html'],
content => $content);
from the _render_html method could help you.
protected function makeRequest($url, $params, $ch=null) {
if (!$ch) {
$ch = curl_init();
}
$opts = self::$CURL_OPTS;
if ($this->useFileUploadSupport()) {
$opts[CURLOPT_POSTFIELDS] = $params;
} else {
$opts[CURLOPT_POSTFIELDS] = http_build_query($params, null, '&');
}
$opts[CURLOPT_URL] = $url;
// disable the 'Expect: 100-continue' behaviour. This causes CURL to wait
// for 2 seconds if the server does not support this header.
if (isset($opts[CURLOPT_HTTPHEADER])) {
$existing_headers = $opts[CURLOPT_HTTPHEADER];
$existing_headers[] = 'Expect:';
$opts[CURLOPT_HTTPHEADER] = $existing_headers;
} else {
$opts[CURLOPT_HTTPHEADER] = array('Expect:');
}
curl_setopt_array($ch, $opts);
$result = curl_exec($ch);
if (curl_errno($ch) == 60) { // CURLE_SSL_CACERT
self::errorLog('Invalid or no certificate authority found, '.
'using bundled information');
curl_setopt($ch, CURLOPT_CAINFO,
dirname(__FILE__) . '/fb_ca_chain_bundle.crt');
$result = curl_exec($ch);
}
if ($result === false) {
$e = new FacebookApiException(array(
'error_code' => curl_errno($ch),
'error' => array(
'message' => curl_error($ch),
'type' => 'CurlException',
),
));
curl_close($ch);
throw $e;
}
curl_close($ch);
return $result;
}
I have built a facebook app, but something went wrong in this piece of code of base_facebook.php.
Whole code is here. All i get everytime are this 2 errors -
1.Warning: curl_setopt_array() [function.curl-setopt-array]: open_basedir restriction in effect. File() is not within the allowed path(s): (/home/:/usr/lib/php:/tmp) in /home/a2424901/public_html/base_facebook.php on line 802
2.Uncaught CurlException: 3: No URL set! thrown in /home/a2424901/public_html/base_facebook.php on line 814
Here is the code of my facebook app i.e.(index.php)
Yeap, non-obvious error message.
But it means, that realpath() returns empty value:
File() is not within the allowed path(s)...
Make sure, that the file passed to realpath() function really exists in the specified path.
Other exceptions in your example were caused by this problem.
By the way, it's good practice to wrap all weak spots (in your example - Facebook API calls) in try-catch blocks.