Good day,
I modified this file.
vendor/laravel/framework/src/Illuminate/Foundation/Bootstrap/HandleExceptions.php
This is the function I modified.
public function handleError($level, $message, $file = '', $line = 0, $context = [])
I made it send me an email. The email has the $message and the $file and the $line.
This is what the email said.
MESSAGE FILE vendor/laravel/framework/src/Illuminate/Filesystem/Filesystem.php LINE 126
The message is blank, but it's running into an error in a file. I open the file.
public function delete($paths)
{
$paths = is_array($paths) ? $paths : func_get_args();
$success = true;
foreach ($paths as $path) {
try {
if (! #unlink($path)) { # the error is here
$success = false;
}
} catch (ErrorException $e) {
$success = false;
}
}
return $success;
}
I am confused. Why was the error not caught by the catch block? What type of error would not give a message to the error handler of laravel? Is there something I can do to get more information regarding the error?
This is our version of Laravel.
Laravel Framework version 5.1.45 (LTS)
First of all the question you have asked is misleading. What you are trying to do is add a custom error handler in laravel which you can achieve by following this URL .
The error you are facing might be caused due to file permission error.
And since there is the # sign before the function call unlink() any errors which are caused by it are suppressed.
Remove the # sign and if the file doesn't exists or if there is an error it would throw it and then catch block would catch it.
Related
i have this entry in my laravel 5.3 log
2016-12-22 17:23:37] local.ERROR:
GuzzleHttp\Exception\ClientException: Client error: POST
https://api.sparkpost.com/api/v1/transmissions resulted in a 400 Bad
Request response: { "errors": [ { "message": "Message generation
rejected", "description": "recipient address suppressed due to
customer p (truncated...)
why does it truncate an important error message? now i cannot figure out what is going wrong...
Because your request throws a Guzzle Exception, as a workaround, instead of calling $e->getMessage(), You can simply try:
$e->getResponse()->getBody()->getContents();
If you don't want to modify the report() method.
Worked nice for me.
The truncating is done by the Guzzle library. It only shows the first 120 characters of the response. I am assuming this is because responses could potentially be very long.
If you would like to see the full message, you should be able to customize how guzzle exceptions are handled.
Update the report() method in your app/Exceptions/Handler.php to something like:
public function report(Exception $exception)
{
// this is from the parent method
if ($this->shouldntReport($exception)) {
return;
}
// this is from the parent method
try {
$logger = $this->container->make(\Psr\Log\LoggerInterface::class);
} catch (Exception $ex) {
throw $exception; // throw the original exception
}
// this is the new custom handling of guzzle exceptions
if ($exception instanceof \GuzzleHttp\Exception\RequestException) {
// get the full text of the exception (including stack trace),
// and replace the original message (possibly truncated),
// with the full text of the entire response body.
$message = str_replace(
rtrim($exception->getMessage()),
(string) $exception->getResponse()->getBody(),
(string) $exception
);
// log your new custom guzzle error message
return $logger->error($message);
}
// make sure to still log non-guzzle exceptions
$logger->error($exception);
}
Note: this is done in the report method, so it only affects what is written to the log. If the exception is dumped to the terminal or to the browser, it will still show the truncated message.
as alternative solution:
hotfix RequestException.php
ta_integration/vendor/guzzlehttp/guzzle/src/Exception/RequestException.php
replace
$size = $body->getSize();
$summary = $body->read(120);
$body->rewind();
if ($size > 120) {
with for example:
$size = $body->getSize();
$summary = $body->read(999);
$body->rewind();
if ($size > 999) {
function
getResponseBodySummary
Edit vendor/guzzlehttp/psr7/src/Message.php
public static function bodySummary(MessageInterface $message, $truncateAt = 999)
Edit vendor/guzzlehttp/psr7/src/functions.php
function get_message_body_summary(MessageInterface $message, $truncateAt = 999)
None of these solutions here helped me. I found a solution here that helped. By the user sidk2020. Here is his solution in case the link breaks:
I did something very adventurous. I modified guzzel's exception handler
guzzel on purpose only reads up 120 bytes of info and prints truncated next to it.
The file is located at : /vendor/guzzlehttp/guzzle/src/Exception/RequestException.php
So I modified that function and below is what my function looks like:
public static function getResponseBodySummary(ResponseInterface $response) {
$body = $response->getBody();
if (!$body->isSeekable() || !$body->isReadable()) {
return null;
}
$size = $body->getSize();
if ($size === 0) {
return null;
}
// Matches any printable character, including unicode characters:
// letters, marks, numbers, punctuation, spacing, and separators.
if (preg_match('/[^\pL\pM\pN\pP\pS\pZ\n\r\t]/', $body)) {
return null;
}
return $body;
}
In vendor/guzzlehttp/psr7/src/functions.php
there's this function:
function get_message_body_summary(MessageInterface $message, $truncateAt = 120)
{
return Message::bodySummary($message, $truncateAt);
}
just change the $truncateAt = 120 to whatever you are confortable with
Hi everyone! In my Laravel application I have a upload function for an Excel file. I got this code from the web and adjusted it to my application. The problem is, it doesn't catch a fatal error exception which is produced when the user submits a file, but hasn't selected a file. I don't understand why it is not being caught. I will add a part of my controller.
public function upload() {
$file = array('thefile' => Input::file('thefile'));
$rules = array('excel' => 'excel');
$validator = Validator::make($file, $rules);
if ($validator->fails()) {
return Redirect::to('UploadExcelFile')->withInput()->withErrors($validator);
}
else {
try{
// FatalErrorException happens in this line!
if (Input::file('thefile')->isValid()) {
$destinationPath = 'uploads';
$fileName = Input::file('thefile')->getClientOriginalName();
Input::file('thefile')->move($destinationPath, $fileName);
Session::flash('success', 'Upload successfully');
$fileNameJSON = exec("python /path/to/script/ExcelToJSON3.py $fileName"); // This returns a full path name of the JSON file that is made...
if ($fileNameJSON == null){
return Redirect::to('/dashboard/input');
}
else {
// Getting the ID from the file that is uploaded
try {
$jsonDecode = json_decode(file_get_contents($fileNameJSON));
} catch (ErrorException $e){
return Redirect::to('/errorpage')->with(array('status'=> 'ErrorException'));
}
A lot of code for handling the data entered....
}catch (FatalErrorException $e){
return Redirect::to('/errorpage')->with(array('status'=> 'FatalErrorException'));
}
}
return true;
}
The error that is given:
FatalErrorException in UploadExcelFileController.php line 35:
Call to a member function isValid() on a non-object
So, I don't understand why this code doesn't handle the error exception and how I could fix this!
Unless you've imported the namespace that FatalErrorException is declared in with "use" you will need to scope the exception, like this:
catch (\Symfony\Component\Debug\Exception\FatalErrorException $e) {
Otherwise you're using whatever namespace your class is in and trying to catch an exception that is declared in that namespace. It looks like your ErrorException is similarly set up.
I'm not sure that the namespace above is the one your class is deriving from, I'm just guessing it is because you're using Laravel.
I want to send mail to an email address whenever any kind of error occurs. Until now I have been working on the development environment. To accomplish this
I used the code from here and implemented that code in app/Exceptions/Handler.php.
When an error occurs, it neither displays the error nor sends an email.
My code is below :
public function report(Exception $e)
{
if ($e instanceof \Exception) {
//dd($e->getLine()); <-- gives output
// emails.exception is the template of your email
// it will have access to the $error that we are passing below
$mail = Mail::send('emails.error_report', ['content' => $e->getMessage()], function ($m) {
$m->to('mail#domain.com', 'Name')->subject('Error Report');
});
return parent::report($e);
}
return parent::report($e);
}
After research of few hours, I have managed to get idea what could be the reason behind this. What I think is, we are already handling an error, and while handling this error, what happens if another error occurs? means, I had an error in the mail function view file. which could not be handled further, while already handling an error.
So the Answer was correct. it was my specific problem. But still i would like to share the code with some improvisations,though code is not much different from the linked thread.
public function report(Exception $e)
{
if ($e instanceof Exception) {
// whenever any error occurs, a mail will be sent to desired email.
// content variable will contain message that you can send to emails.error_report(or whatever) view.
// you can use this variable simply echoing $content.
$content = "There was an error occured on Your Website.following are details of Error:<br><br>Message : ".$e->getMessage()."<br>Line : ".$e->getLine()."<br>File : ".$e->getFile()."";
$mail_content = [
'content' => $content,
];
// if you want to mail that error message to multiple email addresses put those addresses in $emails array.
$emails = array('mail1#domain.com','mail2#gmail.com');
$mail = Mail::send('emails.error_report', $mail_content, function ($message) use ($emails) {
$message->to($emails, 'Maninder')->subject('Error Report');
});
}
return parent::report($e);
}
Please do not forget to add use Illuminate\Support\Facades\Mail; on the top of app/Exceptions/Handler.php file.
After using working code for 1 day, i noticed that i got tons of mails regarding errors that are not needed to be reported to the admin.so i got after making little modification, admin will get email only when any fatal error occurs.though, if you want to be notified for all exceptions you can keep the code as it is above or make modification as below:
if ($e instanceof \Symfony\Component\Debug\Exception\FatalErrorException) {
Instead of:
if ($e instanceof Exception) {
Happy coding for new comers like me! ;)
I have code like this:
try {
$providerError = false;
$providerErrorMessage = null;
$nbg_xml_url = "http://www.somesite.com/rss.php";
$xml_content = file_get_contents($nbg_xml_url);
// ... some code stuff
} catch (Exception $e) {
$providerError = true;
$providerErrorMessage = $e -> getMessage();
$usd = 1;
$rate = null;
$gel = null;
} finally {
// .. Write in db
}`
and problem is that, when file_get_contents can not read url (may be site not responding or something like this..) my code writes error: failed to open stream: HTTP request failed! and execution goes direct to finally block bypass catch block without entering in it..
any ideas?
You can set an empty error handler to prevent the warning and afterward throw a custom exception in case of failure. In this case I would write a custom file_get_content like so:
function get_file_contents($url) {
$xml_content = file_get_contents($url);
if(!$xml_content) {
throw new Exception('file_get_contents failed');
}
return $xml_content;
}
and would use it in your block:
set_error_handler(function() { /* ignore errors */ });
try {
$providerError = false;
$providerErrorMessage = null;
$nbg_xml_url = "http://www.somesite.com/rss.php";
$xml_content = get_file_contents($nbg_xml_url); //<----------
// ... some code stuff
} catch (Exception $e) {
$providerError = true;
$providerErrorMessage = $e -> getMessage();
$usd = 1;
$rate = null;
$gel = null;
} finally {
// .. Write in db
}
Then remember to restore the error handler calling:
restore_error_handler();
Note that when using your own error handler it will bypass the
error_reporting
setting and all errors included notices, warnings, etc., will be passed to it.
$xml_content = file_get_contents($nbg_xml_url);
The function file_get_contents does not throw an exception. Thus an exception will not be thrown if as you say the file is not found.
From the docs:
An E_WARNING level error is generated if filename cannot be found...
This function returns the read data or FALSE on failure. So you could check if $xml_content is FALSE ($xml_content === false) and proceed accordingly.
This is a php code for catching any error or exception.
Throwable is the base interface for any object that can be thrown via a throw statement, including Error and Exception.
This will catch fatal errors too. Without throwable it will not catch fatal errors.
try {
// Code that may throw an Exception or Error.
} catch (Throwable $t) {
// Executed only in PHP 7, will not match in PHP 5.x
} catch (Exception $e) {
// Executed only in PHP 5.x, will not be reached in PHP 7
}
i am trying to download a zip file from server and save it. i get the following error.
the project is in cakePHP
Downloading /server/biruhxml20140925.zip ...
Warning Error: ftp_get(): Transfer complete. in [(pathprefix)/app/Console/Command/Task/ImportUtilityTask.php, line 214]
//server/biruhxml20140925.zip could not be downloaded to (pathprefix)/files/downloaded_files/bild/biruhxml20140925.zip
biruhxml20140925.zip could not be downloaded as the file is not there yet.
this is the function which makes the call.
public function downloadFTPFile ($remoteFile, $localFile) {
$connection = $this->ftpConnection;
ftp_pasv($this->ftpConnection, true);
$this->out(__('Downloading %s ... ', $remoteFile));
try {
if (ftp_get($connection, $localFile, $remoteFile, FTP_BINARY)) {
$this->out(__('Saved %s', $localFile));
return true;
} else {
$this->out(__('%s could not be downloaded to %s', $remoteFile, $localFile));
return false;
}
} catch (Exception $e) {
#unlink($localFile);
$this->out($e->getMessage());
}
$this->nl();
return false;
}
can anyone suggest a work around to get rid of the warning other then setting debug level 0 in core.php
Have you considered, based on the error message, that the file you try to download is not present on the server?
Your code doesn't do a check if the file is there, I would add that and handle that case accordingly.