0

I've a code for command app made on laravel 5.0 with try .. catch and use system command. When there a exception, my catch not work.

use Illuminate\Support\Facades\Log;
...
try {
  system('.dump master | sqlite3 ' . $older . ' > ' . storage_path() . '/tmp/' . $tabla . '.sql' );
} catch ( \Exception $e) {
  Log::alert('Problem import old table '. $tabla . $e->GetMessage());
}

I see my error on shell but not write on my own laravel log. (Log:alert)

3
  • External/system calls do not generate exceptions by themselves. Commented Apr 27, 2016 at 11:29
  • '.dump master? Do you want the system to search for .dump executable in $PATH, or you meant ./dump master that is to execute dump which is in current working directory? I'd recommend constructing absolute paths, anyway. For instance: $cmd = __DIR__ . '/../somewhere/dump master' or $cmd = YOUR_ROOT_DIR . '/bin/dump master' Commented Apr 27, 2016 at 11:34
  • I don't assk about error. I assk about try..catch. I know what it's error. Commented Apr 27, 2016 at 14:02

2 Answers 2

2

You have to gain access over STDERR and, probably, STDOUT. Use proc_open, e.g.:

$desc = [
  1 => ['pipe', 'w'], // STDOUT
  2 => ['pipe', 'w'], // STDERR
];

$proc = proc_open('ls -l . something', $desc, $pipes);
if (is_resource($proc)) {

  if ($out = stream_get_contents($pipes[1])) {
    echo $out;
  }
  fclose($pipes[1]);


  if ($err = stream_get_contents($pipes[2])) {
    fprintf(STDERR, "Error: %s\n", $err);
  }
  fclose($pipes[2]);

  // You can also check the process exit status
  // 0 means success, otherwise error.
  $exit_status = proc_close($proc);
}

Of course, there is no need in STDOUT pipe, if the command redirects it to a file.

And yes, system() won't throw exceptions. Obviously, you can implement your own class which will throw an exception in case if the process exit status is non-zero, or there is something caught in the STDERR pipe:

class MyShellException extends \Exception {}

class MyShell {
  public static function execute($command, &$out = null) {
    if (func_num_args() > 1) {
      $desc[1] = ['pipe', 'w'];
    } else {
      $desc[1] = ['file', '/dev/null'];
    }

    $desc[2] = ['pipe', 'w'];

    $proc = proc_open($command, $desc, $pipes);
    if (is_resource($proc)) {
      if (isset($pipes[1])) {
        $out = stream_get_contents($pipes[1]);
        fclose($pipes[1]);
      }

      if ($err = stream_get_contents($pipes[2])) {
        fclose($pipes[2]);
        throw new MyShellException("Command $command failed: $err");
      }

      if ($exit_status = proc_close($proc)) {
        throw new MyShellException("Command $command exited with non-zero status");
      }
    }
  }
}


try {
  MyShell::execute('ls -l . something', $out);
  echo "Output: $out\n";
} catch (MyShellException $e) {
  if (!empty($out)) {
    echo "Output: $out\n";
  }
  fprintf(STDERR, "MyShell error: " . $e->getMessage());
  exit(1);
}
Sign up to request clarification or add additional context in comments.

Comments

0

Use Throw Exception in php. Here is the reference link to use and a sample example:

<?php
/*
 * 
 * opcode number: 108
 */
try {
    $error = 'Always throw this error';
    throw new Exception($error);

    // Code following an exception is not executed.
    echo 'Never executed';

} catch (Exception $e) {
    echo 'Caught exception: ',  $e->getMessage(), "\n";
}

// Continue execution
echo 'Hello World';
?>

Comments

Your Answer

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

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.