How do I return an error (and message) in a large project?

I am writing a large project and here is a class that I will use often:

class Star
{
    /**
     * Add
     *
     * Add a star to something.
     *
     * @param int $ID   The ID of the thing.
     */

    function Add($ID)
    {
        if($this->Starred($ID))
            return 'You starred it already.';

        if(!$this->Existing($ID))
            return 'The one you tried to star does no longer exist.';

        $this->DB->Star($ID);

        return 'Starred successfully!';
    }
}

$Star = new Star();

      

But I will use it in different ways, for example: single page or inside a function ,

here is the problem, sometimes, I want to know the return code, not the message ,

but when i use it on one page i want it to return messaage,

so if I change the function Add()

to this:

function Add($ID)
{
    if($this->Starred($ID))
        return 0;

    if(!$this->Existing($ID))
        return 1;

    $this->DB->Star($ID);

    return 2;
}

      

Now I can use it in my functions to deal with the error:

/** Leaves a comment */
$Comment->Say('Hello.', $ID);

/** Auto star the post because we commented on it */
if($Star->Add($ID) == 2)
{
    /** Remove the comment because the post does no longer exist */
    $Comment->Remove('Hello.', $ID);

    return 'Sorry ; _ ;, the post does no longer exist.';
}

      

but what if I need to return a message to many other pages?

Do I need to write this code every time?

switch($Star->Add($ID))
{
    case 0:
        return 'You starred it already.';
        break;

    case 1:
        return 'The one you tried to star does no longer exist.';
        break;

    case 2:
        return 'Starred successfully!';
        break;
}

      

I'm just embarrassed, any help would be appreciated.

+3


source to share


2 answers


For a straightforward solution to your code, read the Edit 1 section .

I am currently working on a fairly large project and I am using a class ErrorHandler

that I have created. I found that working with the generic error handler class just got easier.

class ErrorHandler
{
    /**
     * @var string an array containing all the errors set.
     */
    private static $errors = [];

    /**
     * Set an error.
     * 
     * @param string $error - The error message you'd like to set.
     * @return string - The error being set to $errors array.
     */
    public static function add($error)
    {
        return self::$errors[] = $error;
    }

    /**
     * Get all the errors.
     * 
     * @return boolean if the $errors array is empty it will return false, otherwise it will return the errors.
     */
    public static function get()
    {
        foreach (self::$errors as $error) {
            if (empty(trim($error)))
                return false;
        }
        return self::$errors;
    }
}

      

Basically the way I use it, say I need to validate the form input, enter login, I would first check if the user clicked the submit button, then I would use ternary operator

to run some validations and if it fails, I use the class ErrorHandler

.

if(isset($_POST['login'])) {
    $emailAddress = someValidationsHere ? doSomethingWithValidInput : ErrorHandler::add("Email field is empty or format is invalid.");
    $password = someValidationsHere ? doSomethingWithValidInput : ErrorHandler::add("Password field can't be empty and can't use special characters.");

    if(!ErrorHandler::get()) {                    
        echo User::login($emailAddress, $password, $autoLogin);
    } else {
        $errors = ErrorHandler::get();

        foreach($errors as $error) {
            echo $error . "<br/>";
        }
    }
}  

      

So what is the bottom if statement

makes it checks whether not work ErrorHandler::get

function is not false

, which in this case should not show an error message and you can proceed with the code else

page will be displayed with an error, so you can display more than one error, and create your own format.

I prefer this method as it is more of a long term solution, as you can change the ID, then you have to go through all the code and change the code manually. Plus, it gives your code some structure and that your code is clean.

Edit 1

How is this class? Now you know the error codes using the value const

, and you can parse

enter the error code into the message using the function getMessage

. Also your code is more comprehensible and adaptable.



Why is it more ...

understandably?

Because now when you (or anyone else) view this code, they see the clean name from const

, so ALREADY_STARRED_ERROR

let the developer know immediately what the error means.

adapt?

Now you can change your hardcoded errors without affecting your code in any way, so if you want to change it in the future due to a spelling mistake or other errors, you can change the message array.

<?php
class Star
{
    const ALREADY_STARRED_ERROR = 1;
    const NOT_FOUND_ERROR= 2;
    const SUCCESSFUL_ENTRY = 3;

    function getMessage($code)
    {
        $messages = [
            1 => "You starred it already.",
            2 => "The one you tried to star does no longer exist.",
            3 => "Starred successfully!"
        ];

        return $message[$code];
    }

    /**
     * Add
     *
     * Add a star to something.
     *
     * @param int $ID   The ID of the thing.
     */

    function Add($ID)
    {
        if($this->Starred($ID))
            return self::ALREADY_STARRED_ERROR;

        if(!$this->Existing($ID))
            return self::NOT_FOUND_ERROR;

        $this->DB->Star($ID);

        return self::SUCCESSFUL_ENTRY;
    }
}
?>

      

I'd like to think that Edit 1 addressed the issues you had.

sometimes, I want to know the return code, not the message,

but when i use it on one page i want it to return messaage,

+3


source


Place a switch in a function, for example AddWithMessage

:

function AddWithMessage($Star)
{
  switch($Star->Add($ID))
  {
    case 0:
        return 'You starred it already.';
        break;

    case 1:
        return 'The one you tried to star does no longer exist.';
        break;

    case 2:
        return 'Starred successfully!';
        break;
  }
}

      



Then use it on any single page, not Add

+2


source







All Articles