diff --git a/core/modules/views/lib/Drupal/views/Plugin/views/HandlerBase.php b/core/modules/views/lib/Drupal/views/Plugin/views/HandlerBase.php
index a96bc47..3b88f06 100644
--- a/core/modules/views/lib/Drupal/views/Plugin/views/HandlerBase.php
+++ b/core/modules/views/lib/Drupal/views/Plugin/views/HandlerBase.php
@@ -873,7 +873,7 @@ public function submitTemporaryForm($form, &$form_state) {
 
     // Create a new handler and unpack the options from the form onto it. We
     // can use that for storage.
-    $handler = views_get_handler($item['table'], $item['field'], $handler_type, $override);
+    $handler = views_get_handler($item, $handler_type, $override);
     $handler->init($executable, $executable->display_handler, $item);
 
     // Add the incoming options to existing options because items using
diff --git a/core/modules/views/lib/Drupal/views/Plugin/views/display/DisplayPluginBase.php b/core/modules/views/lib/Drupal/views/Plugin/views/display/DisplayPluginBase.php
index f798074..a449410 100644
--- a/core/modules/views/lib/Drupal/views/Plugin/views/display/DisplayPluginBase.php
+++ b/core/modules/views/lib/Drupal/views/Plugin/views/display/DisplayPluginBase.php
@@ -876,8 +876,7 @@ public function getHandlers($type) {
           $handler_type = $type;
         }
 
-        $handler = views_get_handler($info['table'], $info['field'], $handler_type, $override);
-        if ($handler) {
+        if ($handler = views_get_handler($info, $handler_type, $override)) {
           // Special override for area types so they know where they come from.
           if ($handler instanceof AreaPluginBase) {
             $handler->areaType = $type;
diff --git a/core/modules/views/lib/Drupal/views/Plugin/views/exposed_form/InputRequired.php b/core/modules/views/lib/Drupal/views/Plugin/views/exposed_form/InputRequired.php
index 3afcabc..9cb023a 100644
--- a/core/modules/views/lib/Drupal/views/Plugin/views/exposed_form/InputRequired.php
+++ b/core/modules/views/lib/Drupal/views/Plugin/views/exposed_form/InputRequired.php
@@ -83,7 +83,7 @@ function pre_render($values) {
         'content' => $this->options['text_input_required'],
         'format' => $this->options['text_input_required_format'],
       );
-      $handler = views_get_handler('views', 'area', 'area');
+      $handler = views_get_handler($options, 'area');
       $handler->init($this->view, $options);
       $this->displayHandler->handlers['empty'] = array(
         'area' => $handler,
diff --git a/core/modules/views/lib/Drupal/views/Plugin/views/row/RowPluginBase.php b/core/modules/views/lib/Drupal/views/Plugin/views/row/RowPluginBase.php
index e2ac129..635122c 100644
--- a/core/modules/views/lib/Drupal/views/Plugin/views/row/RowPluginBase.php
+++ b/core/modules/views/lib/Drupal/views/Plugin/views/row/RowPluginBase.php
@@ -71,7 +71,7 @@ public function buildOptionsForm(&$form, &$form_state) {
       $relationship_options = array();
 
       foreach ($relationships as $relationship) {
-        $relationship_handler = views_get_handler($relationship['table'], $relationship['field'], 'relationship');
+        $relationship_handler = views_get_handler($relationship, 'relationship');
 
         // If this relationship is valid for this type, add it to the list.
         $data = Views::viewsData()->get($relationship['table']);
diff --git a/core/modules/views/lib/Drupal/views/Plugin/views/sort/GroupByNumeric.php b/core/modules/views/lib/Drupal/views/Plugin/views/sort/GroupByNumeric.php
index ad270f1..31452f5 100644
--- a/core/modules/views/lib/Drupal/views/Plugin/views/sort/GroupByNumeric.php
+++ b/core/modules/views/lib/Drupal/views/Plugin/views/sort/GroupByNumeric.php
@@ -25,7 +25,7 @@ public function init(ViewExecutable $view, DisplayPluginBase $display, array &$o
     parent::init($view, $display, $options);
 
     // Initialize the original handler.
-    $this->handler = views_get_handler($options['table'], $options['field'], 'sort');
+    $this->handler = views_get_handler($options, 'sort');
     $this->handler->init($view, $display, $options);
   }
 
diff --git a/core/modules/views/lib/Drupal/views/Tests/Handler/FieldUnitTest.php b/core/modules/views/lib/Drupal/views/Tests/Handler/FieldUnitTest.php
index 5dfa29b..d5f2eac 100644
--- a/core/modules/views/lib/Drupal/views/Tests/Handler/FieldUnitTest.php
+++ b/core/modules/views/lib/Drupal/views/Tests/Handler/FieldUnitTest.php
@@ -525,15 +525,21 @@ function testIsValueEmpty() {
    */
   public function testClickSortable() {
     // Test that click_sortable is TRUE by default.
-    $plugin = views_get_handler('views_test_data', 'name', 'field');
+    $item = array(
+      'table' => 'views_test_data',
+      'field' => 'name',
+    );
+    $plugin = views_get_handler($item, 'field');
     $this->assertTrue($plugin->click_sortable(), 'TRUE as a default value is correct.');
 
     // Test that click_sortable is TRUE by when set TRUE in the data.
-    $plugin = views_get_handler('views_test_data', 'id', 'field');
+    $item['field'] = 'id';
+    $plugin = views_get_handler($item, 'field');
     $this->assertTrue($plugin->click_sortable(), 'TRUE as a views data value is correct.');
 
     // Test that click_sortable is FALSE by when set FALSE in the data.
-    $plugin = views_get_handler('views_test_data', 'job', 'field');
+    $item['field'] = 'job';
+    $plugin = views_get_handler($item, 'field');
     $this->assertFalse($plugin->click_sortable(), 'FALSE as a views data value is correct.');
   }
 
diff --git a/core/modules/views/lib/Drupal/views/Tests/Handler/HandlerAllTest.php b/core/modules/views/lib/Drupal/views/Tests/Handler/HandlerAllTest.php
index 4e77b35..78e768c 100644
--- a/core/modules/views/lib/Drupal/views/Tests/Handler/HandlerAllTest.php
+++ b/core/modules/views/lib/Drupal/views/Tests/Handler/HandlerAllTest.php
@@ -72,11 +72,15 @@ public function testHandlers() {
       foreach ($info as $field => $field_info) {
         // Table is a reserved key for the metainformation.
         if ($field != 'table' && !in_array("$base_table:$field", $exclude)) {
+          $item = array(
+            'table' => $base_table,
+            'field' => $field,
+          );
           foreach ($object_types as $type) {
             if (isset($field_info[$type]['id'])) {
               $options = array();
               if ($type == 'filter') {
-                $handler = views_get_handler($base_table, $field, $type);
+                $handler = views_get_handler($item, $type);
                 if ($handler instanceof InOperator) {
                   $options['value'] = array(1);
                 }
diff --git a/core/modules/views/lib/Drupal/views/Tests/Handler/HandlerTest.php b/core/modules/views/lib/Drupal/views/Tests/Handler/HandlerTest.php
index 28cc00c..05b3665 100644
--- a/core/modules/views/lib/Drupal/views/Tests/Handler/HandlerTest.php
+++ b/core/modules/views/lib/Drupal/views/Tests/Handler/HandlerTest.php
@@ -101,7 +101,11 @@ function testBreakPhraseString() {
     $null = NULL;
     $this->assertEqual($empty_stdclass, HandlerBase::breakPhraseString('', $null));
 
-    $handler = views_get_handler('node', 'title', 'argument');
+    $item = array(
+      'table' => 'node',
+      'field' => 'title',
+    );
+    $handler = views_get_handler($item, 'argument');
     $this->assertEqual($handler, HandlerBase::breakPhraseString('', $handler), 'The breakPhraseString() method works correctly.');
 
     // test ors
@@ -156,7 +160,11 @@ function testBreakPhrase() {
     // check defaults
     $this->assertEqual($empty_stdclass, HandlerBase::breakPhrase('', $null));
 
-    $handler = views_get_handler('node', 'title', 'argument');
+    $item = array(
+      'table' => 'node',
+      'field' => 'title',
+    );
+    $handler = views_get_handler($item, 'argument');
     $this->assertEqual($handler, HandlerBase::breakPhrase('', $handler), 'The breakPhrase() method works correctly.');
 
     // Generate three random numbers which can be used below;
diff --git a/core/modules/views/lib/Drupal/views/Tests/ModuleTest.php b/core/modules/views/lib/Drupal/views/Tests/ModuleTest.php
index 7831e3d..769efdd 100644
--- a/core/modules/views/lib/Drupal/views/Tests/ModuleTest.php
+++ b/core/modules/views/lib/Drupal/views/Tests/ModuleTest.php
@@ -10,6 +10,7 @@
 /**
  * Tests basic functions from the Views module.
  */
+use Drupal\views\Plugin\views\filter\Standard;
 use Drupal\views\Views;
 
 class ModuleTest extends ViewUnitTestBase {
@@ -21,6 +22,15 @@ class ModuleTest extends ViewUnitTestBase {
    */
   public static $testViews = array('test_view_status');
 
+  /**
+   * Stores the last triggered error, for example via debug().
+   *
+   * @var string
+   *
+   * @see \Drupal\views\Tests\ModuleTest::errorHandler()
+   */
+  protected $lastErrorMessage;
+
   public static function getInfo() {
     return array(
       'name' => 'Views Module tests',
@@ -31,11 +41,17 @@ public static function getInfo() {
 
   /**
    * Tests the views_get_handler method.
+   *
+   * @see views_get_handler()
    */
-  function testviews_get_handler() {
+  public function testViewsGetHandler() {
     $types = array('field', 'area', 'filter');
     foreach ($types as $type) {
-      $handler = views_get_handler($this->randomName(), $this->randomName(), $type);
+      $item = array(
+        'table' => $this->randomName(),
+        'field' => $this->randomName(),
+      );
+      $handler = views_get_handler($item, $type);
       $this->assertEqual('Drupal\views\Plugin\views\\' . $type . '\Broken', get_class($handler), t('Make sure that a broken handler of type: @type are created', array('@type' => $type)));
     }
 
@@ -44,9 +60,13 @@ function testviews_get_handler() {
     foreach ($test_tables as $table => $fields) {
       foreach ($fields as $field) {
         $data = $views_data[$table][$field];
+        $item = array(
+          'table' => $table,
+          'field' => $field,
+        );
         foreach ($data as $id => $field_data) {
           if (!in_array($id, array('title', 'help'))) {
-            $handler = views_get_handler($table, $field, $id);
+            $handler = views_get_handler($item, $id);
             $this->assertInstanceHandler($handler, $table, $field, $id);
           }
         }
@@ -54,8 +74,73 @@ function testviews_get_handler() {
     }
 
     // Test the override handler feature.
-    $handler = views_get_handler('views_test_data', 'job', 'filter', 'standard');
-    $this->assertEqual('Drupal\\views\\Plugin\\views\\filter\\Standard', get_class($handler));
+    $item = array(
+      'table' => 'views_test_data',
+      'field' => 'job',
+    );
+    $handler = views_get_handler($item, 'filter', 'standard');
+    $this->assertTrue($handler instanceof Standard);
+
+    // Test non-existent tables/fields.
+    set_error_handler(array($this, 'customErrorHandler'));
+    $item = array(
+      'table' => 'views_test_data',
+      'field' => 'field_invalid',
+    );
+    views_get_handler($item, 'field');
+    $this->assertTrue(strpos($this->lastErrorMessage, format_string("Missing handler: @table @field @type", array('@table' => 'views_test_data', '@field' => 'field_invalid', '@type' => 'field'))) !== FALSE, 'An invalid field name throws a debug message.');
+    unset($this->lastErrorMessage);
+
+    $item = array(
+      'table' => 'table_invalid',
+      'field' => 'id',
+    );
+    views_get_handler($item, 'filter');
+    $this->assertEqual(strpos($this->lastErrorMessage, format_string("Missing handler: @table @field @type", array('@table' => 'table_invalid', '@field' => 'id', '@type' => 'filter'))) !== FALSE, 'An invalid table name throws a debug message.');
+    unset($this->lastErrorMessage);
+
+    $item = array(
+      'table' => 'table_invalid',
+      'field' => 'id',
+      'optional' => FALSE,
+    );
+    views_get_handler($item, 'filter');
+    $this->assertEqual(strpos($this->lastErrorMessage, format_string("Missing handler: @table @field @type", array('@table' => 'table_invalid', '@field' => 'id', '@type' => 'filter'))) !== FALSE, 'An invalid table name throws a debug message.');
+    unset($this->lastErrorMessage);
+
+    $item = array(
+      'table' => 'table_invalid',
+      'field' => 'id',
+      'optional' => TRUE,
+    );
+
+    views_get_handler($item, 'filter');
+    $this->assertFalse($this->lastErrorMessage, "An optional handler does not throw a debug message.");
+    unset($this->lastErrorMessage);
+
+    restore_error_handler();
+  }
+
+  /**
+   * Defines an error handler which is used in the test.
+   *
+   * @param int $error_level
+   *   The level of the error raised.
+   * @param string $message
+   *   The error message.
+   * @param string $filename
+   *   The filename that the error was raised in.
+   * @param int $line
+   *   The line number the error was raised at.
+   * @param array $context
+   *   An array that points to the active symbol table at the point the error
+   *   occurred.
+   *
+   * Because this is registered in set_error_handler(), it has to be public.
+   * @see set_error_handler()
+   */
+  public function customErrorHandler($error_level, $message, $filename, $line, $context) {
+    $this->lastErrorMessage = $message;
   }
 
   /**
diff --git a/core/modules/views/views.module b/core/modules/views/views.module
index 7f38326..d337318 100644
--- a/core/modules/views/views.module
+++ b/core/modules/views/views.module
@@ -880,21 +880,26 @@ function views_library_info() {
 /**
  * Fetch a handler from the data cache.
  *
- * @param $table
- *   The name of the table this handler is from.
- * @param $field
- *   The name of the field this handler is from.
- * @param $type
+ * @param array $item
+ *   An associative array representing the handler to be retrieved:
+ *   - table: The name of the table containing the handler.
+ *   - field: The name of the field the handler represents.
+ *   - optional: (optional) Whether or not this handler is optional. If a
+ *     handler is missing and not optional, a debug message will be displayed.
+ *     Defaults to FALSE.
+ * @param string $type
  *   The type of handler. i.e, sort, field, argument, filter, relationship
- * @param $override
- *   Override the actual handler object with this class. Used for
- *   aggregation when the handler is redirected to the aggregation
- *   handler.
+ * @param string|null $override
+ *   (optional) Override the actual handler object with this plugin ID. Used for
+ *   aggregation when the handler is redirected to the aggregation handler.
  *
  * @return views_handler
  *   An instance of a handler object. May be views_handler_broken.
  */
-function views_get_handler($table, $field, $type, $override = NULL) {
+function views_get_handler($item, $type, $override = NULL) {
+  $table = $item['table'];
+  $field = $item['field'];
+  $optional = isset($item['optional']) ? $item['optional'] : FALSE;
   // Get the plugin manager for this type.
   $manager = Views::pluginManager($type);;
   $data = Views::viewsData()->get($table);
@@ -931,8 +936,11 @@ function views_get_handler($table, $field, $type, $override = NULL) {
     }
   }
 
+  if (!$optional) {
+    debug(t("Missing handler: @table @field @type", array('@table' => $table, '@field' => $field, '@type' => $type)));
+  }
+
   // Finally, use the 'broken' handler.
-  debug(t("Missing handler: @table @field @type", array('@table' => $table, '@field' => $field, '@type' => $type)));
   return $manager->createInstance('broken');
 }
 
diff --git a/core/modules/views/views_ui/lib/Drupal/views_ui/Form/Ajax/ConfigItem.php b/core/modules/views/views_ui/lib/Drupal/views_ui/Form/Ajax/ConfigItem.php
index 93564b7..606fe44 100644
--- a/core/modules/views/views_ui/lib/Drupal/views_ui/Form/Ajax/ConfigItem.php
+++ b/core/modules/views/views_ui/lib/Drupal/views_ui/Form/Ajax/ConfigItem.php
@@ -96,7 +96,7 @@ public function buildForm(array $form, array &$form_state) {
           if ($type == 'relationship' && $id == $relationship['id']) {
             break;
           }
-          $relationship_handler = views_get_handler($relationship['table'], $relationship['field'], 'relationship');
+          $relationship_handler = views_get_handler($relationship, 'relationship');
           // ignore invalid/broken relationships.
           if (empty($relationship_handler)) {
             continue;
@@ -225,7 +225,7 @@ public function submitForm(array &$form, array &$form_state) {
 
     // Create a new handler and unpack the options from the form onto it. We
     // can use that for storage.
-    $handler = views_get_handler($item['table'], $item['field'], $handler_type, $override);
+    $handler = views_get_handler($item, $handler_type, $override);
     $handler->init($executable, $executable->display_handler, $item);
 
     // Add the incoming options to existing options because items using
diff --git a/core/modules/views/views_ui/lib/Drupal/views_ui/Form/Ajax/ConfigItemGroup.php b/core/modules/views/views_ui/lib/Drupal/views_ui/Form/Ajax/ConfigItemGroup.php
index 96229d4..465c2da 100644
--- a/core/modules/views/views_ui/lib/Drupal/views_ui/Form/Ajax/ConfigItemGroup.php
+++ b/core/modules/views/views_ui/lib/Drupal/views_ui/Form/Ajax/ConfigItemGroup.php
@@ -99,7 +99,7 @@ public function submitForm(array &$form, array &$form_state) {
     $type = $form_state['type'];
     $id = $form_state['id'];
 
-    $handler = views_get_handler($item['table'], $item['field'], $type);
+    $handler = views_get_handler($item, $type);
     $executable = $form_state['view']->get('executable');
     $handler->init($executable, $executable->display_handler, $item);
 
diff --git a/core/modules/views/views_ui/lib/Drupal/views_ui/ViewUI.php b/core/modules/views/views_ui/lib/Drupal/views_ui/ViewUI.php
index 67e0fc6..4038712 100644
--- a/core/modules/views/views_ui/lib/Drupal/views_ui/ViewUI.php
+++ b/core/modules/views/views_ui/lib/Drupal/views_ui/ViewUI.php
@@ -458,7 +458,11 @@ public function submitItemAdd($form, &$form_state) {
         if (isset($types[$type]['type'])) {
           $key = $types[$type]['type'];
         }
-        $handler = views_get_handler($table, $field, $key);
+        $item = array(
+          'table' => $table,
+          'field' => $field,
+        );
+        $handler = views_get_handler($item, $key);
         if ($this->executable->displayHandlers->get('default')->useGroupBy() && $handler->usesGroupBy()) {
           $this->addFormToStack('config-item-group', $form_state['display_id'], $type, $id);
         }
