PHP; Error reporting from inside a function - php

So if a function produces a warning/notice we get the LINE within the function.
I could validate before, during AND/OR after the function call but I am curious is there a way to AUTOMATICALLY be given the error producing LINE_ of the function call that called the function?

You need to use a try catch statement like this:
try{
//your code that errors here
}catch(Exception $e){
echo "Line number:" . $e->getLine();
//you could throw the exception here again
//throw $e;
//or create a new exception and throw that with the data you supply
//$newException = new Exception('New message goes here', 'exception code goes here');
//then throw it
//throw $newException;
exit;
}
Here is the link to the docs:
http://php.net/manual/en/exception.getline.php
You might also be interested in these methods (amongst others) that also belong to the Exception class:
getMessage
getCode
getFile
getMessage
As per your comment and creating a new exception check out the Exception class here:
http://php.net/manual/en/class.exception.php

Use a PHP IDE with a debugger and set breakpoints, watch the call stack.

Related

Function that checks if function executes successfully, otherwise exception. Possible in PHP?

I need some function that will accept a function as the parameter and will run it in try {} catch (Exception $e) {}. If it runs successfully, do nothing, otherwise, throw new Exception. That's something like function-checker, which checks functions if they ran successfully. Anybody can help me or give advice?
Thanks for any replies.
The function should work like that:
function itwillfail () {
echo 10 / 0;
}
check("itwillfail");
Output: Caught exception: Custom exception text here, because it has been thrown as custom.
("check" is that function I need)
What I tried:
function check($func) {
try {
call_user_func($func);
} catch (Exception $e) {
throw new Exception("Custom text here.");
}
}
EDIT: More explained: I need to create function, which do the same as "try" and a lot of different "catch"es for different types of exceptions.
Summarizing your question:
You want a way to call a custom function from a string variable (which you have already figured out that would be via call_user_func($var);.
You then want that function to throw a custom exception error
Confused
What is not clear is the reason you would opt to not define your error handler using the set_error_handler function which would effectively do what your asking and set a switch statement to output different messages based on the error generated.
Example
The following example is not using a call_user_func but it effectively allows you to write how the error will be handled
<?php
function myerror($error_no, $error_msg) {
echo "Error: [$error_no] $error_msg ";
echo "\n Now Script will end";
die();
}
// Setting set_error_handler
set_error_handler("myerror");
$a = 10;
$b = 0;
// Force the error
echo($a / $b);
?>
Not every function throws an exception when they fail. Many functions, especially ones that have been around for a long time, simply trigger PHP errors rather than exceptions.
To handle those, you would use a custom error handler:
https://www.php.net/manual/en/function.set-error-handler.php
So you could set up a custom error handler that would intercept those kinds of failures and throw them as exceptions. The whole point of that function is to do what you're trying to do - handle errors in a custom way.

How can I find out all the errors that can possibly be thrown by a block of PHP code?

I want to know what errors can be thrown that I am not catching, for dynamic code - not static code. For example, my code may run without throwing any Exceptions for 10 years and then throw UncaughtException
I want to specifically (non-generically) catch every type of Exception that can be thrown by the methods I am using. How can I know what Exceptions MAY be thrown by these methods?
I want to non-generically catch every type of error that can possibly be thrown for a section of PHP code.
Examples of exceptions that may be thrown:
PDOException
ExpiredException
Now I have this around everything:
try{
...
}catch(Exception $e){
...
}
I'd like to replace it with something like this:
try{
...
}catch(PDOException $e){
...
}catch(ExpiredException $e){
...
}catch(Exception $e){
...
}
I'd like to be confident that I am catching all different kinds of Exception that can be thrown by the methods in the section of code
And if I catch all Exceptions individually, will it be safe to remove this part?:
catch(Exception $e){
...
}
Or are there methods which will simply throw Exception?
My solution preference list (1 is the most-preferred solution):
1: A flag I can turn on that will cause php.exe to warn me about each and every possible type of Exception that is not specifically being caught
2: A way to individually check each method and see what errors can be thrown. Is the documentation the only way to check? or is there some IDE or PHP block that will tell me which Exceptions may be thrown by individual methods?
You can set callback function by using register_shutdown_function() which will call on every end of your php code execution. In this callback function you can check whether any error occurs or not using error_get_last().
For Example:
// Register shutdown function
register_shutdown_function("shutdownTracker");
// Define all error types you want to catch and handle
define('E_FATAL', E_ERROR | E_PARSE | E_CORE_ERROR | E_COMPILE_ERROR | E_USER_ERROR | E_RECOVERABLE_ERROR);
function shutdownTracker() {
$error = error_get_last(); // This will return empty if no error occurs while executing php code.
if(!empty($error) && ($error['type'] & E_FATAL)) {
// Write your code here to handle you error
}
}
Note: You should include this code on top of your code.
Well if you are talking exceptions, you already have the answer
try{
...
}catch(PDOException $e){
...
}catch(ExpiredException $e){
...
}catch(Exception $e){
echo get_class($e); // get's the class of unrecorded exceptions.
//catches any exceptions missed by the above
}
Now if you are talking about "errors" you can do is use a custom error handler
if(!function_exists('myErrorHandler')){
function myErrorHandler($severity, $message, $file = 'UNKNOWN', $line = 'UNKNOWN')
{
throw new ErrorException(
$message,
1,
$severity,
$file,
$line
);
}
set_error_handler('myErrorHandler');
}
What it does is convert all PHP errors to exceptions or rather to ErrorExceptoins.
Now you can go a step further and use these other two functions.
register_shutdown_function
AND
set_exception_handler
I'm actually working on porting what I use to it's own stand alone github project. Right after I finish my eJinn project, which you may be interested in. eJinn is designed to build exception classes based off a config file, so you can have one error per exception file and unique error codes in a project.
You can catch all exceptions without even call try.
function hello($e)
{
if ($e instanceof PDOException){
echo "something".
}else echo $e->getMessage();
}
set_exception_handler('hello');
this should catch all exceptions.
UPDATE 2
I've edited the code so you know what exceptions will be thrown using get_class();
class mycustomException extends Exception{} // making new exception
function hello($e)
{
if ($e instanceof PDOException){ // exception already known
echo "something";
}else{
echo get_class($e); // get exception name.
}
}
set_exception_handler('hello');
throw new mycustomException(); // throw exception that we made.

Custom messages for php exception handling

I'm using an external file with $errmsg array for displaying errors, like:
'app_init' => 'Cannot initialize application',
Using conditionals, I call the function to display the message on failure:
if(!$condition)
{
$arraywithmessages->functionforfiltering($err,'app_init',$aim);
}
...where $err is the array of messages, and $aim is predefined method of publishing error (e-mail, view, etc...)
Now I'd like to make use of Exception Handling, but I don't know where to start. Can anyone help? This doesn't seem to work:
try {
if (!$condition) {
throw new Exception('app_init');
}
// continue
} catch (Exception $e) {
$arraywithmessages->functionforfiltering($err,$e->getMessage(),$aim);
}
I don't know exactly what you want to achive but you should remember that try, catch should be used wisely. It should be used for Exceptional situations only. If you don't use them in that way then it's GOTO code.
About exceptions, remmeber that you can extend Exception class and make your own exceptions and catch them in multiple catch blocks, there is also finally block.
About the constructor of Exception. It has the second param which is $code you can use it to show proper message.
$err = array(0x1 => 'my error app init');
try {
if (!$condition) {
throw new Exception('app_init', 0x1);
}
// continue
} catch (Exception $e) {
echo $err[$e->getCode()]; //it shouldn't be only echo it should do some tries to fix the code close streams etc. not just echo.
}
There is also function
set_exception_handler(). which:
Sets the default exception handler if an exception is not caught within a try/catch block. Execution will stop after the exception_handler is called.
Consider using it. There are a lot of things that can be found in manual.

Detect if an exception has been thrown manually without using a custom exception class

I got a try-catch block in my php application like this:
try {
if ($userForgotToEnterField) {
throw new Exception('You need to fill in your name!');
}
...
doDifferentThingsThatCanThrowExceptions();
...
} catch (ExpectedException $e) {
$template->setError('A database error occured.');
} catch (Exception $e) {
$template->setError($e->getMessage());
}
I would like to only output $e->getMessage() for the exceptions I have manually thrown with a custom error text and not the ones that have been thrown by the other code as these might contain sensitive information or very technical info that the user should not see.
Is it possible to differentiate from a manually thrown exception and a random exception thrown by some method without using a custom exception class?
I agree that it might be best to just write your own exceptions. If for whatever reason you don't want to, you could set a custom error message and a custom error code (the second parameter for the Exception constructor.) Check each thrown Exception if the error code is yours, and display only those:
public Exception::__construct() ([ string $message = "" [,int $code = 0[, Exception $previous = NULL ]]] )
and then use getCode
I've thought about this a bit and I'd say that what you are doing DOES call for a custom exception class. If you want to get around it (which in the end is going to be more confusing), you would basically create a global (or same-scope) variable that all exceptions can modify, and in your throw block flag it.
$threwCustomException = false;
try {
if ($userForgotToEnterField) {
throw new Exception('You need to fill in your name!');
$threwCustomException = true;
}
...
doDifferentThingsThatCanThrowExceptions();
...
} catch (ExpectedException $e) {
$template->setError('A database error occured.');
} catch (Exception $e) {
if($threwCustomException){
//Whatever custom exception handling you wanted here....
}
$template->setError($e->getMessage());
}
That's the best I can think of. However, this is a bad idea, and it's the whole reason you are allowed to create your own exception classes. I know you're not looking for this answer, but since you look like you're trying not to create a TON of extra code, I would just extend Exception to "CustomException" or some other name specific to your project, and throw that for all cases, and handle it that way.
Hope that helps.

Cannot destroy active lambda function

Can someone tell me the most common reasons to see this error in PHP:
Cannot destroy active lambda function in...
I'm guessing that somewhere there is code that's trying to destroy a closure that contains a reference to itself and the compiler is annoyed at this.
We get these more regularly than I'd like and I'm wondering what pattern we are using that's the likely culprit that's causing it.
I would attach a code snippet but the error typically points to a file not to a line in a file that might provide a hint.
There is similar bug posted in php.net regarding the same. Below is the link .
Hope it will be helpful to you.
https://bugs.php.net/bug.php?id=62452
Such a fatal error will result in code like this:
set_exception_handler(function ($e) {
echo "My exception handler";
restore_exception_handler();
throw new Exception("Throw this instead.");
});
throw new Exception("An exception");
Or like this:
function destroy_handler() {
restore_exception_handler();
}
function update_handler() {
destroy_handler();
}
set_exception_handler(function ($e) {
echo "My exception handler";
update_handler();
throw new Exception("Throw this instead.");
});
throw new Exception("An exception");
When an exception is thrown the callback given to set_exception_handler() is executed and as soon as the restore_exception_handler() is called, the fatal error occurs because the same reference to that closure is being destroyed (or reassigned) inside its own scope (the same goes in the example of hanskrentel at yahoo dot de in the link posted by Sameer K).
You can see from the second example that, even with nested scopes, the same occurs. This is because restore_exception_handler will destroy the last set exception handler, and not a copy of it (it's like re-assigning a variable or unset it while you are still evaluating the expression that will give the variable an initial value).
If you say that the error in your code points to another file, I suggest you to check all the calls in your lambda which execution "jumps" in functions and or methods in other files and check there if you are reassigning or destroying a reference to the lambda itself.
The set_exception_handler will return the previous exception handler:
Returns the name of the previously defined exception handler, or NULL on error. If no previous handler was defined, NULL is also returned.
php.net: set_exception_handler
<?php
class MyException extends Exception {}
set_exception_handler(function(Exception $e){
echo "Old handler:".$e->getMessage();
});
$lastHandler = set_exception_handler(function(Exception $e) use (&$lastHandler) {
if ($e instanceof MyException) {
echo "New handler:".$e->getMessage();
return;
}
if (is_callable($lastHandler)) {
return call_user_func_array($lastHandler, [$e]);
}
throw $e;
});
Trigger the exception handler:
throw new MyException("Exception one", 1);
Output: New handler:Exception one
throw new Exception("Exception two", 1);
Output: Old handler:Exception two

Categories