codeigniter email->attach errors - codeigniter

I'm wondering how I might catch email class errors prior to codeigniter actually sending.
For example, if the function cannot find the attachment, it would seem that there isn't an error that gets thrown within the framework (at least that I can determine).
$this->email->attach('/path/to/file.ext');
I've tried:
if( !$this->email->attach('/path/to/file.ext') ){
echo $this->email->print_debugger();
}
and no error is thrown.
I only notice that the attachment isn't attached after the send command is issued $this->email->send();
In fact, the email is sent, but obviously without the attachment, but also without the $this->email->message() content -- just an empty email body.
It would seem that the print_debugger() function really doesn't get populated until the send() function is called. If I intentionally point to a file that doesn't exist, the print_debugger() function will throw this error (only after the send() function is called):
Unable to locate the following email attachment: /path/to/file.ext<br />Your message
has been successfully sent using the following protocol: sendmail<br /><pre>
User-Agent: CodeIgniter
Date: Thu, 23 May 2013 09:27:49 -0400
<snip>
When I call the print_debugger() function prior to the send() function, the result is only an empty array (I'm guessing, as the output from that call is just <pre> </pre>).
I'm hoping to catch this error prior to the send() function being called from within the framework.
I do understand that I can use PHP natively to check for file_exists, but it'd be nice, IMHO, for codeigniter to throw some error earlier than it does.
if( file_exists('/path/to/file.ext') ):
$this->email->attach('/path/to/file.ext');
else:
echo 'ERROR';
endif;
Thoughts/Suggestions/Comments?

This isn't CodeIgniter specifc per-se. I think you are looking for PHP Exceptions. Example:
try {
$this->email->attach('/path/to/file.ext');
} catch (Exception $e) {
echo 'Caught exception: ', $e->getMessage();
}

Related

Pass request to exception

Since I started logging exceptions on a production site I'm noticing a lot of them, especially 404s, more than I would expect for a site with barely any traffic, and I'd like to get to the bottom of whether they're genuine users or just bots. To help with this, I want to capture the URL that the user was trying to visit before being redirected to the 404 route, so I can keep track of which non-existent routes are being mistakenly hit. I think I'm correct in assuming this URL should be available in the request, and that I just need to store the request and pass it through to the exception.
What's the best way to do this in Laravel 8 onwards?
Catch 404 exceptions in Handler(App\Exceptions\Handler).
If you see Rendering Exceptions
By default, the Laravel exception handler will convert exceptions into
an HTTP response for you. However, you are free to register a custom
rendering closure for exceptions of a given type. You may accomplish
this via the renderable method of your exception handler.
The closure passed to the renderable method should return an instance
of Illuminate\Http\Response, which may be generated via the response
helper. Laravel will deduce what type of exception the closure renders
by examining the type-hint of the closure:
so in the register method,call renderable
public function register()
{
$this->renderable(function (NotFoundHttpException $e, $request) {
Log::alert("404",[
"fullUrl"=>$request->fullUrl(),
"path"=>$request->path(),
"message" =>$e->getMessage()
]);
return response()->view('errors.404', [], $e->getStatusCode());
});
}
Also, don't forget to import and use
Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
EDIT: just a few hours of using this solution in production, with the benefit of the newly-added request URLs, has confirmed for me just how many of these HTTP 4xx errors are junk - mostly automated bots and maybe a few script kiddies trying common routes. For this reason I've added some logic to ignore 404 and 405 errors, and may still add others that mostly contribute noise to the logfile.
This was harder than it should have been, but this is the solution I'm currently using to log the request with all exceptions. It's probably not the cleanest way to do it, but it works perfectly for my needs. Thanks to John Lobo's answer for pointing me in the right direction.
It works by inspecting each instance of the Exception class and using PHP's instanceof to check whether it's a HTTP exception or not. If it is, it gets logged with the request URL and returns a view with a status code. If it's a generic non-HTTP exception, it gets logged with the request URL and returns another view with no status code (or you can keep the default exception behaviour by removing the return block, which renders a blank screen in production).
public function register()
{
$this->renderable(function (Exception $exception, $request) {
$url = $request->fullUrl();
if ($exception instanceof HttpException) {
$status = $exception->getStatusCode();
// Do not log HTTP 404 and 405s errors for reasons that will
// become apparent after a few hours of logging 404s and 405s
if(($status !== 404) && ($status !== 405)) {
Log::warning("Error $status occurred when trying to visit $url. Received the following message: " . $exception->getMessage());
}
return response()->view("errors.error", [
"exception" => $exception,
"status" => $status
],
$status
);
} else {
$status = $exception->getCode();
Log::warning("Exception $status occurred when trying to visit $url. Received the following message: " . $exception->getMessage());
return response()->view("errors.exception", [
"exception" => $exception,
"status" => $status
]);
}
});
// Optionally suppress all Laravel's default logging for exceptions, so only your own logs go to the logfile
$this->reportable(function (Exception $e) {
})->stop();
}

Laravel: Where does report() store the error messages?

According to the Laravel handling error documentation I've put this code snippet in one of my functions:
try {
// Send an email...
} catch (Throwable $e) {
report($e);
return false;
}
Now I want to check out the error messages but I have no idea where they are stored.
I've tried both storage/logs/laravel.log and var/log/apache2/error.log but I found nothing.
Where does report() store the error message ?
It depends on your config/logging.php.
By default it should be the stack channel.
If your channel is set up to daily it willl create a file per day (e.g: laravel-2022-05-16.log
Otherwise you can leave the single channel it will put everything in storage/logs/laravel.log

prevent Lumen from showing default 500 Internal Server Error on API responses

I have a Route defined as:
$app->post('api/v1/Subject','SubjectController#createSubject');
And in the Controller I have the following code:
public function createSubject(Request $request){
$Subject = Subject::create($request->all());
return response()->json($Subject);
}
Now, when someone sends incorrect data, it triggers a Query Exception - "SQLSTATE[23000]: Integrity constraint violation:" which is understood.
However, what I want is: I want do not want Lumen to send its own default Error Page in API Response. I want to capture this error event and send my own customized response. How can I do that?
Since I could not find a solution, I tried to add my own view at: /resources/views/errors/500.blade.php but Lumen is even ignoring this template. Please help. Ideally, I would want to capture this error event and send my own customized response.
EDIT:
Lumen was reporting two exceptions - PDOException and QueryException at the 500 error response. So, to get a custom error message, I put the following code in side function render() in app\Exceptions\Handler:
public function render($request, Exception $e)
{
if($e instanceof PDOException){
return response('It is my Custom response for PDOException that caused 500 error response.');
}
if($e instanceof QueryException){
return response('It is my Custom response for QueryException that cuased 500 error response.');
}
return parent::render($request, $e);
}

Respect\Validation\Validator - using an array while catching errors

I am attempting to catch errors utilizing the Respect\Validation\Validator opensource PHP class. I used their example to create an array of checks. Although that seems to work ok, I then attempted to catch any error messages so that I could display it to the user. I saw no method to do so as a full array (check everything, store all messages in an array). So instead, I tried to cycle through using the check method in Validator.
This is inside of a class method, using the F3 (Fat Free) Framework.
I end up with the following error:
Cannot use object of type Respect\Validation\Validator as array
The code is below. What is the proper way to perform this task using arrays here? Thank you for the assistance!
$registerValidator =
Respect\Validation\Validator::attribute('email', Respect\Validation\Validator::email()->length(1,null)->notEmpty())
->attribute('address', Respect\Validation\Validator::stringType()->length(3,null)->notEmpty())
->attribute('city', Respect\Validation\Validator::alpha()->length(2,60)->notEmpty())
->attribute('state', Respect\Validation\Validator::alpha()->length(2,2)->notEmpty())
->attribute('zip', Respect\Validation\Validator::intType()->length(5,5)->notEmpty());
foreach($this->f3->get('POST') as $key => $value){
try{
$registerValidator[$key]->check($value);
} catch (\InvalidArgumentException $e) {
$errors = $e->getMainMessage();
$this->userMessage($errors, 'warning');
$this->f3->reroute('/register');
}
}
I have also tried to use the assert method as found in their docs, but utilizing the below change, I get a different error at a 500 Server Internal Error, instead of seeing my echo:
try{
$registerValidator->assert($this->f3->get('POST'));
} catch (Respect\Validation\Validator\NestedValidationException $e) {
$errors = $e->getMessages();
echo($errors); // I can't even get here.
foreach($errors as $error){
$this->userMessage($error, 'warning');
}
$this->f3->reroute('/register');
}
With this 500 Error, rather than seeing my Echo, so the page stops loading entirely.
All of the required rules must pass for ...
You cannot really use the Validator class as an array like you're doing on $registerValidator[$key]->check($value). The object in $registerValidator variable contain the chain of rules to validate an input.
In your case I believe the input is the array coming from the POST, so first of all you should use the Key validator instead of Attribute.
However the real reason why you cannot catch the errors is because you have a typo on your catch statement, the class name should be Respect\Validation\Exceptions\NestedValidationException like it's stated in the documentation, not Respect\Validation\Validator\NestedValidationException.

Authorize.net for Magento throwing "unable to read response or response is empty"

We have a 1.6 Magento site that is sending out "Payment Transaction Failed" emails. The server is throwing the error "unable to read response or response is empty". We are using the Authorize.net payment gateway. It's been working just fine and there have been no changes to the site. What could be causing this error?
This error message, exception, is thrown here Zend_Http_Client around line 993
If you take a look at the code, it means that the response could not be read, possibly because of a timeout, network glitch or something like that.
Here is the code snippet
$response = $this->adapter->read();
if (! $response) {
/** #see Zend_Http_Client_Exception */
#require_once 'Zend/Http/Client/Exception.php';
throw new Zend_Http_Client_Exception('Unable to read response, or response is empty');
}

Resources