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(); }