4

In PHP, if a value is considered "unknown" (not per se invalid) should this raise a logic or runtime exception?

<?php
function foo($bar) {
    // logic
    if(!is_string($bar)) {
        throw new \InvalidArgumentException('invalid *argument*');
    }
    if(strlen($bar) < 4) {
        throw new \DomainException('invalid *bar*');
    }
    static $knownBars = array('bar1', 'bar2');
    if(!in_array($knownBars)) {
        throw new \DomainException('unknown *bar*');
        //throw new \UnexpectedValueException('unknown *bar*');
    }

    // runtime
    $bar;
}

The first 2 exceptions are obvious, however the last one remains a bit unclear to me. Both seem to make sense; a logic/domain error as we expect one of a defined data-set, a runtime/unexpected value error as we actually got a unexpected value.

Which one should i throw?

Also what if the logic part is a single setter method and we want to replace the static array (data-set) with a database lookup instead... Is it OK to expect runtime exceptions in logic code due database failure, etc? Or should we move the database lookup to the runtime code and still throw a logic exception if "bar" is considered unknown?

Roland Franssen
  • 1,038
  • 1
  • 11
  • 22
  • *(related)* [OutOfRange vs OutOfBounds](http://stackoverflow.com/questions/8193798/outofrangeexception-vs-outofboundsexception) – Gordon Jan 05 '13 at 12:43
  • (related) [When would you use a DomainException](http://stackoverflow.com/questions/1102979/when-would-you-throw-a-domainexception-in-php) – Gordon Jan 05 '13 at 12:56
  • I'm a bit late to the party but I suggest forgetting that the SPL exceptions ever existed unless you need to catch one that is thrown somewhere in the SPL (infrequently happens). I'm trying to work out a more sane hierarchy here: https://github.com/morrisonlevi/Ardent/blob/master/Exceptions.md – Levi Morrison Jan 07 '13 at 04:13
  • did any of the given answers solve your problem? If so, please accept the answer so the question is marked as solved. If not, please update your question and point out why none of the given answers so far helped. – Gordon Mar 01 '13 at 12:16

2 Answers2

15

Logic Exceptions are for errors that occur at compile time. Since PHP has no compile time in the sense this is meant, it usually is interpreted as "errors occuring during development", (like when the developer forgot to pass a depedency or something) while Runtime Exceptions are for unforseen errors (usually stemming from User Input) when the code is run.

But frankly, the entire Spl Exception hierarchy is Fubar. So just use what you want or create your own.

Also see https://wiki.php.net/rfc/spl-improvements/exceptions

Gordon
  • 312,688
  • 75
  • 539
  • 559
  • Create your own.. so.. should UnknownBarException extend from \LogicException or \Runtime.. :P I guess i'll go with logic as "unknown x" implies there is a known data-set for x. – Roland Franssen Jan 05 '13 at 12:44
  • @RolandFranssen from Exception. The only reason to use RuntimeException and LogicException is for semantics. – Gordon Jan 05 '13 at 12:45
  • Imho \DomainException (> Logic > Exception) as UnknownBar *ALWAYS* implies a defined data-set for bars (the domain) and i like to maintain that semantic. – Roland Franssen Jan 05 '13 at 12:48
  • @Roland A DomainException could easily be a Runtime Exception as well, since it refers to the [mathematical domain](https://en.wikipedia.org/wiki/Domain_of_a_function), e.g. the range of valid input to a function. If a user provides a value outside that range it's clearly not a Logic Exception. – Gordon Jan 05 '13 at 12:51
  • "If a user provides a value" Who is the user? The developer? because as far as I understand a developer passing a value/argument outside a defined range is clearly a logic error. – Roland Franssen Jan 05 '13 at 13:04
  • @Roland End User. Not the Developer. The person using the application (Runtime). Not the guy wiring it together (Logic). – Gordon Jan 05 '13 at 13:08
  • let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/22237/discussion-between-roland-franssen-and-gordon) – Roland Franssen Jan 05 '13 at 13:09
  • there was a lot of discussion about the Spl Exception dilemma in the past. Feel free to ask around in http://chat.stackoverflow.com/rooms/11/php – Gordon Jan 05 '13 at 13:11
0

I'll go with domain for this one as the data-set is static (and therefor checked in setFoo())... I would go with unexpectedvalue if the data-set is dynamic (and therefor checked in doSomethingWithFoo()).

Yousha Aleayoub
  • 4,532
  • 4
  • 53
  • 64
Roland Franssen
  • 1,038
  • 1
  • 11
  • 22