BarryBones41
BarryBones41

Reputation: 1491

Returning useful error messages with PHP

I don't understand how to properly create and return useful error messages with PHP to the web.

I have a class

class Foo {
    const OK_IT_WORKED = 0;
    const ERR_IT_FAILED = 1;
    const ERR_IT_TIMED_OUT = 3;

    public function fooItUp(){
        if(itFooed)
          return OK_IT_WORKED;
        elseif(itFooedUp)
          return ERR_IT_FAILED;
        elseif(itFooedOut)
          return ERR_IT_TIMED_OUT;
    }
}

And another class that uses this class to do something useful, then return the result to the user. I am just wondering where I put the string value for all my error messages.

class Bar {
    public function doFooeyThings(stuff){
        $res = $myFoo->fooItUp();
        // now i need to tell the user what happened, but they don't understand error codes
        if($res === Foo::OK_IT_WORKED)
           return 'string result here? seems wrong';
        elseif ($res === Foo::ERR_IT_FAILED)
           return Foo::ERR_IT_FAILED_STRING; // seems redundant?
        elseif($res === Foo:ERR_IT_TIMED_OUT)
           return $res; // return number and have an "enum" in the client (js) ?
    }

}

Upvotes: 3

Views: 79

Answers (2)

Crackertastic
Crackertastic

Reputation: 4913

One solution is to use exceptions in conjunction with set_exception_handler().

<?php

set_exception_handler(function($e) {
    echo "Error encountered: {$e->getMessage()}";
});

class ErrorMessageTest
{
    public function isOk()
    {
        echo "This works okay. ";
    }

    public function isNotOkay()
    {
        echo "This will not work. ";
        throw new RuntimeException("Violets are red, roses are blue!! Wha!?!?");
    }
}

$test = new ErrorMessageTest();

$test->isOk();
$test->isNotOkay();

The set_exception_handler() method takes a callable that will accept an exception as its parameter. This let's you provide your own logic for a thrown exception in the event it isn't caught in a try/catch.

Live Demo

See also: set_exception_handler() documentation

Upvotes: 1

dimlucas
dimlucas

Reputation: 5141

You should avoid returning error states whenever possible. Use exceptions instead. If you've never used exceptions before you can read about them here

There multiple ways you can utilize exceptions in your example. You could create custom exceptions for every error or for every category of error. More on custom exceptions here or you could create an instance of the default Exception class supplying it the error messages as strings.

The code below follows the second approach:

class Foo {
    const OK_IT_WORKED = 0;
    const ERR_IT_FAILED = 1;
    const ERR_IT_TIMED_OUT = 3;

    public function fooItUp(){
        if(itFooed)
          return OK_IT_WORKED;
        else if(itFooedUp)
           throw new Exception("It failed")
        else if(itFooedOut)
           throw new Exception("Request timed out");
    }
}

I'm sure you can think of some more elegant messages than the ones I used. Anyway, you can then go ahead and handle those exceptions on the caller method using try/catch blocks:

class Bar {
    public function doFooeyThings(stuff){
        try
        {
           $res = myFoo->fooItUp();
        }
        catch(Exception $e)
        {
           //do something with the error message
        }

    }

}

Whatever exception is thrown from fooItUp will be "caught" by the catch block and handled by your code.

Two things you should also consider are:

  • It's best not to show your users detailed information about errors because those information could be used by users with malicious intent

  • Ideally you should have some kind of global exception handling

Upvotes: 2

Related Questions