I am using FB Connect and the PHP class called Facebook, that is provided by FB. Whenever something goes wrong FB throws Fatal Error and application dies. That's great for testing but now very nice for production code. I've looked through code and can't find a way to disable that but may be I overlooked something. So, is there any way to disable fatal errors other than looking through their class and removing every line like this
throw new FacebookApiException($result);
You should catch exceptions, not remove them.
try {
//do something with the facebook api
}
catch (FacebookApiException $e) {
//an error occured, handle it
}
And btw: fatal errors are different from exceptions.
Related
I'm developing my own PHP framework and my code althought is working like it should, it's getting bigger and bigger; that of course leads to multiple ways for my framework to break, so I have decided it is time to implement Exception handling like any other PHP framework does, that 'nice' error view that tells you what might went wrong.
I have done my research and kind of understand how the Extension PHP default class works, I know that I'm able to extend this class and customize the error messages.
I also know that to trigger an Exception you gotta throw it and catch it with a "try/catch" statement, somethin like this...
class MyCustomException extends \Exception()
{
// My stuff
}
public function dontBeZero($number)
{
if ($number == 0) {
throw new MyCustomException('You gave me zero!!');
}
}
try {
dontBeZero(0);
} catch (MyCustomException $e) {
echo '<pre>';
$e->getMessage();
echo '</pre>';
}
I understand that, but my real question is: How does this popular frameworks such as Laravel, Symfony, etc manage to throw you a pretty message showing you what the error was, where do they keep all the logic that verifies whether it should or should not throw an exception, and most importantly where did they catch them?.
Most frameworks show these errors via a custom error handler. A popular one used by laravel is whoops.
You just need to register it as a custom handler, and you'll see the pretty error pages:
$whoops = new \Whoops\Run;
$whoops->pushHandler(new \Whoops\Handler\PrettyPageHandler);
$whoops->register();
Keep in mind, you should disable these on production (so that your stack traces/code isn't exposed).
See the two functions set_error_handler and set_exception_handler. These functions allow you to register a callback function which is called when an error or exception occurs.
These callback functions are called by the Php runtime and provided with error details as arguments. The error details include error line number, stack trace, file name and more. The callback function can then format and display this information
I'm studying PHP right now and I'm using w3schools, but when I use the code below my page gets broken (stops from where the code is):
<?php
function myException($exception) {
echo "<b>Exception:</b> " . $exception->getMessage();
}
set_exception_handler('myException');
throw new Exception('Uncaught Exception occurred');
?>
This code is for creating an exception when no catch block was found.
I tried the others examples in the page and everything works fine. I thought it may be happening because there is no try block, but I'm confused and I don't know how to use it in this situation.
Thanks in advance!
set_exception_handler documentation from php.net:
http://php.net/manual/en/function.set-exception-handler.php
Execution will stop after the exception_handler is called.
Actually the output you are getting is correct.
As stated in W3Schools documentation set_exception_handler() only sets a user-defined function to handle all uncaught exceptions (as in the example you quoted above). So the output should be something like this:
Exception: Uncaught Exception occurred
Please notice the form of exception is what you have defined in your function (myException); which means first it prints the word Exception: and then it prints the reason (message) of exception, in this case Uncaught Exception occurred.
EDIT
As mentioned in the comments the error handler causes the script to stop being executed. To avoid this situation is better always to handle exceptions using try catch blocks.
P.S: I'd suggest you to use better resources other than W3Schools (like the PHP documentations itself) if you are starting to learn PHP.
try this. Hope it helps. If not please let me know.
function myException($exception) {
try {
throw new Exception("Some error message");
} catch(Exception $e) {
echo $e->getMessage();
}
}
set_exception_handler('myException');
throw new Exception('Uncaught Exception occurred');
Pretty new to laravel, so I'm not exactly sure how it handles errors and how best to catch them.
I'm using a 3rd party game server connection library that can query game servers in order to pull data such as players, current map etc..
This library is called Steam Condenser : https://github.com/koraktor/steam-condenser
I have imported this using composer in my project and all seems to be working fine, however I'm having trouble with catching exceptions that are thrown by the library.
One example is where the game server you are querying is offline.
Here is my code:
public function show($server_name)
{
try{
SteamSocket::setTimeout(3000);
$server = server::associatedServer($server_name);
$server_info = new SourceServer($server->server_ip);
$server_info->rconAuth($server->server_rcon);
$players = $server_info->getPlayers();
$total_players = count($players);
$more_info = $server_info->getServerInfo();
$maps = $server_info->rconExec('maps *');
preg_match_all("/(?<=fs\)).*?(?=\.bsp)/", $maps, $map_list);
}catch(SocketException $e){
dd("error");
}
return view('server', compact('server', 'server_info', 'total_players', 'players', 'more_info', 'map_list'));
}
If the server is offline, it will throw a SocketException, which I try to catch, however this never seems to happen. I then get the error page with the trace.
This causes a bit of a problem as I wish to simply tell the end user that the server is offline, however I cannot do this if I can't catch this error.
Is there something wrong with my try/catch? Does laravel handle catching errors in this way? Is this an issue with the 3rd party library?
A couple things:
Does the trace lead to the SocketException or to a different error? It's possible that a different error is being caught before the SocketException can be thrown.
Your catch statement is catching SocketException. Are you importing the full namespace at the top of your PHP file? use SteamCondenser\Exceptions\SocketException;
Also for debugging purposes, you could do an exception "catch all" and dump the type of exception:
try {
...
}catch(\Exception $e){
dd(get_class($e));
}
If you still get the stack trace after trying the above code, then an error is being thrown before the try/catch block starts.
I'm experiencing something eerily similar to this question about an uncatchable PHP error thrown by the Facebook PHP SDK except for the fact that I'm not using PHP namespaces at all. This other question is also close, but doesn't explain why the error is uncatchable. Further, in my case, I have a Facebook app that issues a Facebook Graph API call against an object that the current user has blocked. This is certainly awkward, but legal for the purposes of this particular app. That means I need to catch the error, not prevent the user from making the search in the first place.
The fatal error's output in my development environment looks like this:
Fatal error: Uncaught GraphMethodException: Unsupported get request. thrown in /path/to/apps/lib/facebook/src/base_facebook.php on line 1271
So, Facebook's Graph API correctly returns an error as a result of the API call, citing "Unsupported get request." However, the Facebook PHP SDK seems to throw this as an uncatchable error, and I don't know why.
I've tried code like the following catch blocks with no success:
try {
$response = $facebook->api("/$some_id_of_object_current_user_has_blocked");
} catch (FacebookApiException $e) {
// Why does this never get caught?
} catch (Exception $e) {
// Similarly, this also never gets caught!
} catch (GraphMethodException $e) {
// Still can't catch this exception, and I don't grok why. :(
}
For the sake of ridiculous completeness, I've also tried namespaces including things like this:
try {
$response = $facebook->api("/$some_id_of_object_current_user_has_blocked");
} catch (\FacebookApiException $e) {
} catch (\Exception $e) {
} catch (\FacebookApiException\GraphMethodException $e) {
} catch (\GraphMethodException $e) {
} catch (... $e) {
}
Further investigation lead me to try catching this in the base_facebook.php file itself, where it seems to get thrown, in the protected Facebook::_graph method. And sure enough, it is catchable there. The original code at about line 879 of base_facebook.php is:
if (is_array($result) && isset($result['error'])) {
$this->throwAPIException($result);
// #codeCoverageIgnoreStart
}
Wrapping this call to throwAPIException() with a try...catch block works:
if (is_array($result) && isset($result['error'])) {
try {
$this->throwAPIException($result);
// #codeCoverageIgnoreStart
} catch (Exception $e) {
// WORKS!
}
}
So if it works there, why can't I catch this exception from my own scripts? Am I missing something fundamental about the way PHP error handling works?
Alternatively, is there a way for a Facebook app to get a list of all the objects a Facebook user has blocked, such as other Facebook users a user has blocked? I'm familiar with Graph API enough to know that there's a way for an app to access a list of all users a page has blocked, but that's specifically not what I'm looking for.
Thanks for your time.
It's apparently uncatchable because it relates to the permissions your app uses.
In your case, it looks like you were trying to GET the same thing as me, which requires the permission: read_stream
It makes sense that they would make this sort of thing uncatchable - but you'd think the facebook devs could do something a little more friendly...
Adding the try/catch around $this->throwAPIException($result); works in suppressing the error message but I would recommend checking the inputs to your functions to ensure they exist and are valid.
For example, check to see if $SESSION['fb<your_app_id>_access_token'] exists and is not null before passing this to any functions. If this is not set or is null, none of the functions that rely on it will work and you can catch the potential issue before communicating with Facebook's servers, which speeds up your application by skipping a function you can determine ahead of time will fail, and resolve issues quicker by asking for corrections proactively instead of re-actively.
I also was seeing this error which apparently was caused by my app not having the appropriate permissions, as #rm-vanda stated. Because the app id does not have the permissions, a token is not returned which results in the error you are seeing.
Hope that helps!
I'm attempting to post an open graph action to the Facebook Graph API but receiving an OAuth Exception (#3501) User is already associated to the <object>. That's all well and good, I expect Facebook to throw that exception. I get some other exceptions regarding authenticating a user (maybe with old/stale sessions, whatever).
My question is, has anyone else experienced that this exception is uncatchable in php? In this specific example (of posting graph actions) I am absolutely wrapping the call to the api in a try/catch statement; but I still get the fatal error.
<?php
try {
//publishing to open graph
$this->fb->api('/me/app:action', 'POST', array(
'object' => 'http://www.domain.com/path/to/graph/object',
));
}
catch (Exception $e)
{
/*
We may get here if the user has already posted this action before...
or if our session somehow went sour
or bc facebook is down...
or one of any other 1000 reasons the graph api is currently
sucking...
in any case it doesn't much matter, this is not a mission critical
thing to worry about; if we don't post the graph action - we don't
post the graph action..nbd.
*/
}
The above code is the snippet the publishes the graph action (generalized, because the content of it isn't important to this example).
I realize that the Exception that the Facebook PHP SDK is throwing is a FacebookApiException but that class extends Exception. I can't for the life of me figure out why in the name of all things logical, I can't catch my exception like this.
Has anyone experienced this issue? Is this a bug in the FB PHP SDK? Am I missing something else here? Thanks for your help!
Also, for reference, the relevant parts of the FB PHP SDK are here:
FacebookAPIException Definition (base_facebook.php line 30)
Throwing OAuthException (base_facebook.php line 1105
Edit 5/1/12
After some more investigation, it turns out that this "Exception" isn't really being treated like an exception at all. Typical Exceptions print out a stack trace back to the method call which resulted in throwing the exception. These "OAuthExceptions" do not. Also, typical exceptions pring out their error string a bit differently, for example:
PHP Fatal error: Uncaught exception 'Exception' with message 'foo' /path/to/file.php:10
or
PHP Fatal error: Uncaught exception 'MyException' with message 'stupid php' /path/to/file:10
#0 /path/to/file.php(17): doTest()
#1 {main}
thrown in /path/to/file.php on line 10
In this particular case, we don't get any of that, and it looks much more like a typical fatal error:
PHP Fatal error: Uncaught OAuthException: (#3501) User is already associated \
to the <object> object on a unique action type <action>. Original Action ID: \
123123123
thrown in /path/to/app/libs/fb/base_facebook.php on line 1107, \
referer: http://www.domain.com/path/to/page
I can't make any sense of why this forsaken "Exception" is so weird/uncatchable.
The Solution:
I figured out the answer to my own question; I've added it below - it's developer error, not a bug. The answer is below.
Also, this very well could be part of a bug, if you wanted to say that being able to reference a class definition as a type-hint to the catch definition which didn't exist (or wasn't available in the current namespace) is a bug.
So, something that's not outline above is that I'm utilizing PHP namespaces. This is a big gotchta since namespaces are relatively new to php, it's super easily overlooked I feel. Regardless, it's a pretty silly oversight/error.
If you're in a defined namespace (that is, not the root (\) namespace) you don't have direct access to the Exception class. Instead of php throwing a warning about not knowing what that class is, it just ignores the fact that it doesn't know what it is - and doesn't catch the exception.
Solution 1:
import the exception class:
<?php
use \Exception;
// ...codes
try {
//...codes
}
catch (Exception $e)
{
//...codes
}
Solution 2:
provide the full path to the exception class:
<?php
try {
//.....
}
catch (\Exception $e)
{
// voila.
}