Repository: iterative/dvc

Issue:
pipeline show: broken `-c` option
```
DVC version: 0.41.3
Python version: 3.7.3
Platform: Darwin-18.6.0-x86_64-i386-64bit
```

I'm getting the following error when trying to use `dvc pipeline show -c <stage.dvc>` with any stage file in our [get started repo](https://github.com/iterative/example-get-started):

```console
Traceback (most recent call last):
  File "/usr/local/Cellar/python/3.7.3/Frameworks/Python.framework/Versions/3.7/lib/python3.7/logging/__init__.py", line 1037, in emit
    stream.write(msg + self.terminator)
TypeError: unsupported operand type(s) for +: 'NoneType' and 'str'
Call stack:
  File "/usr/local/bin/dvc", line 10, in <module>
    sys.exit(main())
  File "/usr/local/lib/python3.7/site-packages/dvc/main.py", line 38, in main
    ret = cmd.run_cmd()
  File "/usr/local/lib/python3.7/site-packages/dvc/command/base.py", line 60, in run_cmd
    return self.run()
  File "/usr/local/lib/python3.7/site-packages/dvc/command/pipeline.py", line 156, in run
    self.args.locked,
  File "/usr/local/lib/python3.7/site-packages/dvc/command/pipeline.py", line 32, in _show
    logger.info(stages[n].cmd)
Message: None
Arguments: ()
```


Discussion:

Resolving patch:
diff --git a/dvc/command/pipeline.py b/dvc/command/pipeline.py
--- a/dvc/command/pipeline.py
+++ b/dvc/command/pipeline.py
@@ -29,6 +29,8 @@ def _show(self, target, commands, outs, locked):
 
         for n in nodes:
             if commands:
+                if stages[n].cmd is None:
+                    continue
                 logger.info(stages[n].cmd)
             elif outs:
                 for out in stages[n].outs:
diff --git a/dvc/logger.py b/dvc/logger.py
--- a/dvc/logger.py
+++ b/dvc/logger.py
@@ -10,6 +10,12 @@
 import colorama
 
 
+class LoggingException(Exception):
+    def __init__(self, record):
+        msg = "failed to log {}".format(str(record))
+        super(LoggingException, self).__init__(msg)
+
+
 class ExcludeErrorsFilter(logging.Filter):
     def filter(self, record):
         return record.levelno < logging.ERROR
@@ -149,6 +155,12 @@ def _progress_aware(self):
         progress.clearln()
 
 
+class LoggerHandler(logging.StreamHandler):
+    def handleError(self, record):
+        super(LoggerHandler, self).handleError(record)
+        raise LoggingException(record)
+
+
 def setup(level=logging.INFO):
     colorama.init()
 
@@ -159,14 +171,14 @@ def setup(level=logging.INFO):
             "formatters": {"color": {"()": ColorFormatter}},
             "handlers": {
                 "console": {
-                    "class": "logging.StreamHandler",
+                    "class": "dvc.logger.LoggerHandler",
                     "level": "DEBUG",
                     "formatter": "color",
                     "stream": "ext://sys.stdout",
                     "filters": ["exclude_errors"],
                 },
                 "console_errors": {
-                    "class": "logging.StreamHandler",
+                    "class": "dvc.logger.LoggerHandler",
                     "level": "ERROR",
                     "formatter": "color",
                     "stream": "ext://sys.stderr",


Test patch:
diff --git a/tests/func/test_add.py b/tests/func/test_add.py
--- a/tests/func/test_add.py
+++ b/tests/func/test_add.py
@@ -296,8 +296,9 @@ def test(self):
             self.assertEqual(ret, 0)
             self.assertEqual(file_md5_counter.mock.call_count, 3)
 
+            ls = "dir" if os.name == "nt" else "ls"
             ret = main(
-                ["run", "-d", self.DATA_DIR, "dir {}".format(self.DATA_DIR)]
+                ["run", "-d", self.DATA_DIR, "{} {}".format(ls, self.DATA_DIR)]
             )
             self.assertEqual(ret, 0)
             self.assertEqual(file_md5_counter.mock.call_count, 3)