4
\$\begingroup\$

Is there a cleaner way to do this?

    try {
        $ffprobe      = FFProbe::create();
        $streams      = $ffprobe->streams($infile);
        $videoStreams = $streams->videos();
        $audioStreams = $streams->audios();

        if (!$videoStreams) {
            throw new Exception("Could not find a video stream for file: " . $infile . PHP_EOL);
        }

    } catch (RuntimeException $e) {
        throw $e;
    }
\$\endgroup\$
5
  • \$\begingroup\$ If all you're doing is catching the exception to throw it again, why catch it in the first place? Do away with the catch block, that'll make your code a hell of a lot cleaner \$\endgroup\$ Aug 19, 2014 at 7:23
  • \$\begingroup\$ The question was not whether to throw it, it was rather if this construct is the best way to do this. This code is called at a higher level with a try catch block. \$\endgroup\$ Aug 19, 2014 at 7:39
  • \$\begingroup\$ I don't think you understand my comment: I know this code is called somewhere else, but given that you have a try-catch block there, why have an internal one, too? Any exception that is thrown, will propagate until it is caught, or reaches the global scope. If it reaches the outer scope, and no exception handler is registered, only then will your application crash. \$\endgroup\$ Aug 19, 2014 at 7:49
  • \$\begingroup\$ Supposing this code is in a library, the end result is that it throws an exception. When calling this code, are you suggesting to not do it inside a try ... catch block? \$\endgroup\$ Aug 19, 2014 at 11:41
  • 1
    \$\begingroup\$ No, I'm not. I'm just saying that catching an exception, just to throw it again is pointless. If you hadn't caught the exception, it would've been caught by the outer try-catch block. If there is no try-catch, then the exception handler would've been invoked. If there was no exception handler, only then would your app crash. Bottom line: try-catch-throw is pointless, only catch when you actually handle the exception \$\endgroup\$ Aug 19, 2014 at 11:58

1 Answer 1

3
\$\begingroup\$

The way you did it is pretty much the standard way to bubble exceptions up the stack. Basically something like:

function a(){ 
    throw new Exception("Exceptional!"); 
}

function b(){
    try{
        a();
    } catch (Exception $e){
        throw $e;
    }
} 

try{
    b();
} catch (Exception $e){
    echo $e->getMessage();
}

This will output:

Exceptional!

Do note that if you in b() do throw new Exception($e), you'll get:

exception 'Exception' with message 'Exceptional!' in sandboxed.php:1 
Stack trace: 
    #0 php(5): a() 
    #1 php(12): b() 
    #2 {main}

For your code however, you'd have to make sure that you are your try/catch block is within another try/catch block, otherwise you will end up with an uncaught exception error.

try{
    try {
        $ffprobe      = FFProbe::create();
        $streams      = $ffprobe->streams($infile);
        $videoStreams = $streams->videos();
        $audioStreams = $streams->audios();

        if (!$videoStreams) {
            throw new Exception("Could not find a video stream for file: " . $infile . PHP_EOL);
        }

    } catch (RuntimeException $e) {
        throw $e;
    }
} catch (Exception $e){
    echo $e->getMessage();
}

May I ask why you are bubbling exceptions like this rather than erroring out on a caught exception?

EDIT Fail often:

try{
    $ffprobe = FFProbe::create();

    try {
        $streams = $ffprobe->streams($infile);
    } catch (RuntimeException $e) {
        throw $e;
    }

    $videoStreams = $streams->videos();
    $audioStreams = $streams->audios();

    if (!$videoStreams) {
        throw new Exception("Could not find a video stream for file: " . $infile . PHP_EOL);
    }
} catch (Exception $e){
    echo $e->getMessage();
}
\$\endgroup\$
3
  • \$\begingroup\$ Good question. The call to $ffprobe->streams is actually the line that throws the runtime exception, so I could reduce the scope of the try catch block and then check for the presence of $videoStreams. Thanks for the response. \$\endgroup\$ Aug 19, 2014 at 7:00
  • \$\begingroup\$ Seems to me like that's the wrong way to go about doing that. Remember to fail early and fail often. Wrap the try/catch around the $ffprobe->streams() call instead of continuing through the block. I've updated my code to reflect the fail early, fail often commentary. \$\endgroup\$
    – jsanc623
    Aug 19, 2014 at 15:30
  • \$\begingroup\$ jsanc623 agreed \$\endgroup\$ Aug 20, 2014 at 14:46

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.