---
title: "Ruby 2.6 added option to raise exception in Kernel#system"
description:
  "The BigBinary team's lesson on Ruby 2.6 adding an option to raise exception
  in Kernel#system"
canonical_url: "https://www.bigbinary.com/blog/ruby-2-6-added-option-to-raise-exception-in-kernel-system"
markdown_url: "https://www.bigbinary.com/blog/ruby-2-6-added-option-to-raise-exception-in-kernel-system.md"
---

# Ruby 2.6 added option to raise exception in Kernel#system

The BigBinary team's lesson on Ruby 2.6 adding an option to raise exception in
Kernel#system

- Author: Amit Choudhary
- Published: April 25, 2018
- Categories: Ruby 2.6, Ruby

We write scripts to automate setup and deployment of Rails applications. In
those scripts, in many places, we need to run system commands like
`bundle install`, `rake db:create`, `rake db:migrate` and many more.

Let's suppose we need to run migrations using `rake db:migrate` in a Rails
project setup script. We can use the `Kernel#system` method.

```ruby
irb> system('rake db:migrate')
```

#### Ruby 2.5.0

Executing `system` returns `true` or `false`. Another feature of `system` is
that it eats up the exceptions.

Let's suppose our migrations can run successfully. In this case the `system`
command for running migrations will return true.

```ruby
irb> system('rake db:migrate')
 => true
```

Let's suppose we have a migration that is trying to add a column to a table
which does not exist. In this case, the `system` command for running migrations
will return false.

```ruby
irb> system('rake db:migrate')
== 20180311211836 AddFirstNameToAdmins: migrating =============================
-- add_column(:admins, :first_name, :string)
rake aborted!
StandardError: An error has occurred, this and all later migrations canceled:

PG::UndefinedTable: ERROR:  relation "admins" does not exist
: ALTER TABLE "admins" ADD "first_name" character varying
.
.
.
Tasks: TOP => db:migrate
(See full trace by running task with --trace)
 => false
```

As we can see, even when there is a failure in executing system commands, the
return value is false. Ruby does not raise an exception in those cases.

However, we can use `raise` explicitly to raise an exception and halt the setup
script execution.

```ruby
irb> system('rake db:migrate') || raise('Failed to run migrations')
== 20180311211836 AddFirstNameToAdmins: migrating =============================
-- add_column(:admins, :first_name, :string)
rake aborted!
StandardError: An error has occurred, this and all later migrations canceled:

PG::UndefinedTable: ERROR:  relation "admins" does not exist
: ALTER TABLE "admins" ADD "first_name" character varying
.
.
.
Tasks: TOP => db:migrate
(See full trace by running task with --trace)
Traceback (most recent call last):
        2: from /Users/amit/.rvm/rubies/ruby-2.5.0/bin/irb:11:in `<main>'
        1: from (irb):4
RuntimeError (Failed to run migrations)
```

#### Ruby 2.6.0-preview1

Ruby 2.6 make our lives easier by providing an option `exception: true` so that
we do not need to use `raise` explicitly to halt script execution.

```ruby
irb> system('rake db:migrate', exception: true)
== 20180311211836 AddFirstNameToAdmins: migrating =============================
-- add_column(:admins, :first_name, :string)
rake aborted!
StandardError: An error has occurred, this and all later migrations canceled:

PG::UndefinedTable: ERROR:  relation "admins" does not exist
: ALTER TABLE "admins" ADD "first_name" character varying
.
.
.
Tasks: TOP => db:migrate
(See full trace by running task with --trace)
Traceback (most recent call last):
        3: from /Users/amit/.rvm/rubies/ruby-2.6.0-preview1/bin/irb:11:in `<main>'
        2: from (irb):2
        1: from (irb):2:in `system'
RuntimeError (Command failed with exit 1: rake)
```

Ruby 2.6 works the same way as previous Ruby versions when used without the
`exception` option or used with `exception` set as false.

```ruby
irb> system('rake db:migrate', exception: false)
== 20180311211836 AddFirstNameToAdmins: migrating =============================
-- add_column(:admins, :first_name, :string)
rake aborted!
StandardError: An error has occurred, this and all later migrations canceled:

PG::UndefinedTable: ERROR:  relation "admins" does not exist
: ALTER TABLE "admins" ADD "first_name" character varying
.
.
.
Tasks: TOP => db:migrate
(See full trace by running task with --trace)
 => false
```

Here is the relevant [commit](https://github.com/ruby/ruby/commit/fb29cffab0)
and [discussion](https://bugs.ruby-lang.org/issues/14386) for this change.

`system` is not the only way to execute scripts like these. We wrote
[a blog](https://blog.bigbinary.com/2012/10/18/backtick-system-exec-in-ruby.html)
6 years ago which discusses the differences between running commands using
`backtick`, `exec`, `sh`, `popen3`, `popen2e` and `Process.spawn`.

The Chinese version of this blog is available
[here](http://madao.me/yi-ruby-2-6-kernel-de-system-fang-fa-zeng-jia-shi-fou-pao-chu-yi-chang-can-shu/).

## Links

- [Human page](https://www.bigbinary.com/blog/ruby-2-6-added-option-to-raise-exception-in-kernel-system)
