Welcome Guest, Not a member yet? Register   Sign In
Exceptions exceptions...
#1
Question 
(This post was last modified: 04-17-2020, 11:00 AM by Gary.)

Hi,

The CI framework throws a variety of exceptions… many of them are difficult (or perhaps just inconvenient) to place within a try-catch block.

Is there some easy way to be able to intercept these in a more generic way at the final output stage so that every occurrence of an exception is gracefully handled (perhaps with a generic response), even in the case of an exception being thrown somewhere where it’s not anticipated?

Some of the reason for this is that if one is using CSRF tokens that are updated on every submission, a single system-generated response will throw the server/client out of sync and break the website (or cause the client to be unnecessarily booted).

I’ve read though everything I can find in the CI user documentation on Error Handling, Using Exceptions, Custom Exceptions and Replacing Common Functions, and have even considered to use Events… as best I can tell, only way this can (sensibly) be done is by changing/extending the Core System Class:  CodeIgniter\HTTP\Response.  However, being a noob, I take note of the warning that is on ALL of the relevant documentation pages: “Messing with a core system class has a lot of implications, so make sure you know what you are doing before attempting it”

Any advice would be appreciated, thanks.

As an aside, I started off trying to configure Apache's config: with ErrorDocument 500 "Cutom 500" (as a global, then a virtual host, and also as a directory option, as well as in .htaccess)... and that seems to get totally ignored, which is why I packed up on the idea of doing it this way.
Reply
#2

(This post was last modified: 04-19-2020, 03:16 PM by Leo.)

Hi Gary,
Any progress? I've just encountered same issue in my project.


Details: A user downloads an image from some website that is labeled with a .jpeg extension. It is actually a .heic image (if microsoft paint is to be trusted) and I get an exception during attempted upload. Instead, when this happens, I want to display an info message: "This image type is unsupported/image has additional copyright measures added. You may try and open it in ms paint and re-save it as .jpeg (works 100%)". Instead I get throw ImageException::forInvalidImageCreate('Ima'); in GDHandler.php

So far solved like this:
PHP Code:
try {
     
//my library function for image uploading, editing
     $new_images $simpleImg->upload();
} catch (\
CodeIgniter\Images\Exceptions\ImageException $e) {
     session()->setFlashdata('message',
'This image type is unsupported/image has additional copyright measures added. You may try and open it in ms paint and re-save it as .jpeg (works 100%)');


This code catches ALL exceptions within \CodeIgniter\Images\Exceptions\ImageException
How do I display my own message exactly for forInvalidImageCreate?
You can see things I made with codeigniter here: itart.pro its not overly impressive as I have very little time to learn.
Reply
#3

(This post was last modified: 04-19-2020, 05:00 PM by Gary.)

Hey Leo,

I suspect simply checking if $e is that particularly type of exception inside your catch block, and then returning your Flashdata message if it is (look in \system\\CodeIgniter\Images\Exceptions\ImageException.php for all of the CI system image exception types), and also follow this check with a rethrow of the exception if it's not of your Images.unsupportedImageCreate exception... may work.

Depending on how you've done your validation, I suspect you could also push a message into the validation error array (instead of using Flashdata), so that it'll show up like any of the other- more automated- existing validation checks using something like this:

Code:
$validation->setError('field_name_where_error_will_show', 'custom_message_and_user_insults_here');    // see \system\Validation\Validation.php for setError() details
Reply
#4

(This post was last modified: 04-20-2020, 01:04 AM by Leo.)

PHP Code:
try {
    $new_images $simpleImg->upload();
} catch (
ImageException $e) {
    if(substr($e066) === 'CodeIgniter\Images\Exceptions\ImageException: Your server does not') {
          $validation->setError('img_path'lang('mixed.imageException', [], 'custom'));
    }



Thanks for the tip with validation. It is now a lot easier to read than a flash message, along with other possible errors.
You can see things I made with codeigniter here: itart.pro its not overly impressive as I have very little time to learn.
Reply
#5

(This post was last modified: 04-20-2020, 03:06 AM by Gary.)

That looks like it'll work... to be rigorously correct, it should also have a re-throw of any other exception below your mixed.imageException check.
Reply
#6

(This post was last modified: 04-20-2020, 06:07 AM by Leo.)

No its not working. I've been hacking at it for a while but I can't get the picture error to display with other errors. I get other form field errors showing fine, but not my custom one, not showing at all.

PHP Code:
        $model = new ProductsModel();
        $validation Services::validation();
        $validation->setRules($model->validationRules);

        if(isset($_POST['submit'])) {

            $validation->withRequest($this->request)->run();

            //check image
            if(isset($_FILES['img_path'])) {
                $upload_config = (object)[
                    'width' => 280,
                    'height' => 200,
                    'dir' => WRITEPATH.'uploads',
                    'name' => 'img_path',
                    'multiple' => false,
                    'fit_or_cover' => 'cover',
                    'crop' => true,
                    'keepName' => false,
                    'returnOnlyFileName' => true
                
];
                $simpleImg = new SimpleImg($upload_config);
                try {
                    $new_images $simpleImg->upload();
                } catch (ImageException $e) {
                    //forInvalidImageCreate
                    if(substr($e066) === 'CodeIgniter\Images\Exceptions\ImageException: Your server does not') {
                        $validation->withRequest($this->request)->setError('img_path'lang('mixed.imageException', [], 'custom'));
                    }
                }
            }



And 
in my view file I have this:

$errors = \Config\Services::validation()->listErrors() ?? null;
echo 
$errors
You can see things I made with codeigniter here: itart.pro its not overly impressive as I have very little time to learn.
Reply
#7

(This post was last modified: 04-20-2020, 07:09 AM by Gary.)

Did you try it with only TWO parameters, as what the framework's function definition appears to call for?

As in:
$validation->setError('field_name_where_error_will_show', 'custom_message_and_user_insults_here');

As an aside, using setError will overwrite any existing error messages in previous validation calls... and is purely intended as an easy way to inject error messages into the program flow to use one's existing error display. So, without my having followed though/checked what's happening in the framework validation code, to be safe, it is best applied as the last validation-related call in the controller before the error display is invoked in the view.

Looking at your code, it looks like if the imageException is called, it will overwrite all of the other validations... it probably needs to be done in two steps (because of this overwriting, not appending to):
1) general validation of the upload -> display these validation errors in the view
2) once general validation all clear, process the file -> catch these exceptions -> use setError to inject these into the validation error message array -> display validation errors (which now contains the injected message) in the view
Reply
#8

(This post was last modified: 04-20-2020, 10:39 AM by Leo. Edit Reason: found solution )

I figured it out. It was a very dumb mistake on my part. I develop in English, with my comments, etc. in English. But I make Russian websites. So when I switched language in app/config - back to english - EVERYTHING WORKED AS EXPECTED.

However this mistake brought me back to my comment from 9 hours ago.

if(substr($e, 0, 66) === 'CodeIgniter\Images\Exceptions\ImageException: Your server does not') {
          $validation->setError('img_path', lang('mixed.imageException', [], 'custom'));
}

This solution is flawed. I shouldn't match my exception with string contained in $e...I somehow have to figure out another way to figure out if its an exception from forInvalidImageCreate. For now, I'll just have to check for string in English and Russian until I figure out an easier way to catch/figure out exceptions.

UPDATE: solution:
PHP Code:
try {
     $new_images $simpleImg->upload();
} catch (
ImageException $e) {
     //forInvalidImageCreate
     if(strpos($elang('Images.unsupportedImageCreate'))) {
          $validation->setError('img_path'lang('mixed.imageException', [], 'custom'));
     }

You can see things I made with codeigniter here: itart.pro its not overly impressive as I have very little time to learn.
Reply
#9

And using only the portion that won't change: if(substr($e, 0, 45) === 'CodeIgniter\Images\Exceptions\ImageException:') {... ?
Reply




Theme © iAndrew 2016 - Forum software by © MyBB