Repository: mitmproxy/mitmproxy

Issue:
Mitmproxy crashes, when giving it the file without flows data
##### Steps to reproduce the problem:

1. Open mitmproxy.
2. Press `Shift L` to load flows from the file.
3. Set the filepath with any data excluding flows data. For example: `/home/kajoj/myphoto.jpg`

I am seeing:
```
Traceback (most recent call last):
  File "/home/kajoj/Mitmproxy/mitmproxy/mitmproxy/io/io.py", line 43, in stream
    tnetstring.load(self.fo),
  File "/home/kajoj/Mitmproxy/mitmproxy/mitmproxy/io/tnetstring.py", line 178, in load
    raise ValueError("not a tnetstring: missing or invalid length prefix")
ValueError: not a tnetstring: missing or invalid length prefix

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "/home/kajoj/Mitmproxy/mitmproxy/mitmproxy/tools/console/master.py", line 216, in run
    self.loop.run()
  File "/home/kajoj/Mitmproxy/mitmproxy/venv/lib/python3.5/site-packages/urwid/main_loop.py", line 278, in run
    self._run()
  File "/home/kajoj/Mitmproxy/mitmproxy/venv/lib/python3.5/site-packages/urwid/main_loop.py", line 376, in _run
    self.event_loop.run()
  File "/home/kajoj/Mitmproxy/mitmproxy/venv/lib/python3.5/site-packages/urwid/main_loop.py", line 682, in run
    self._loop()
  File "/home/kajoj/Mitmproxy/mitmproxy/venv/lib/python3.5/site-packages/urwid/main_loop.py", line 719, in _loop
    self._watch_files[fd]()
  File "/home/kajoj/Mitmproxy/mitmproxy/venv/lib/python3.5/site-packages/urwid/raw_display.py", line 393, in <lambda>
    event_loop, callback, self.get_available_raw_input())
  File "/home/kajoj/Mitmproxy/mitmproxy/venv/lib/python3.5/site-packages/urwid/raw_display.py", line 493, in parse_input
    callback(processed, processed_codes)
  File "/home/kajoj/Mitmproxy/mitmproxy/venv/lib/python3.5/site-packages/urwid/main_loop.py", line 403, in _update
    self.process_input(keys)
  File "/home/kajoj/Mitmproxy/mitmproxy/venv/lib/python3.5/site-packages/urwid/main_loop.py", line 503, in process_input
    k = self._topmost_widget.keypress(self.screen_size, k)
  File "/home/kajoj/Mitmproxy/mitmproxy/mitmproxy/tools/console/window.py", line 293, in keypress
    k = super().keypress(size, k)
  File "/home/kajoj/Mitmproxy/mitmproxy/venv/lib/python3.5/site-packages/urwid/container.py", line 1116, in keypress
    return self.footer.keypress((maxcol,),key)
  File "/home/kajoj/Mitmproxy/mitmproxy/mitmproxy/tools/console/statusbar.py", line 149, in keypress
    return self.ab.keypress(*args, **kwargs)
  File "/home/kajoj/Mitmproxy/mitmproxy/mitmproxy/tools/console/statusbar.py", line 104, in keypress
    self.prompt_execute(self._w.get_value())
  File "/home/kajoj/Mitmproxy/mitmproxy/mitmproxy/tools/console/statusbar.py", line 124, in prompt_execute
    msg = p(txt)
  File "/home/kajoj/Mitmproxy/mitmproxy/mitmproxy/tools/console/commandexecutor.py", line 17, in __call__
    ret = self.master.commands.call(cmd)
  File "/home/kajoj/Mitmproxy/mitmproxy/mitmproxy/command.py", line 221, in call
    return self.call_args(parts[0], parts[1:])
  File "/home/kajoj/Mitmproxy/mitmproxy/mitmproxy/command.py", line 212, in call_args
    return self.commands[path].call(args)
  File "/home/kajoj/Mitmproxy/mitmproxy/mitmproxy/command.py", line 101, in call
    ret = self.func(*pargs)
  File "/home/kajoj/Mitmproxy/mitmproxy/mitmproxy/command.py", line 251, in wrapper
    return function(*args, **kwargs)
  File "/home/kajoj/Mitmproxy/mitmproxy/mitmproxy/addons/view.py", line 361, in load_file
    for i in io.FlowReader(f).stream():
  File "/home/kajoj/Mitmproxy/mitmproxy/mitmproxy/io/io.py", line 55, in stream
    raise exceptions.FlowReadException("Invalid data format.")
mitmproxy.exceptions.FlowReadException: Invalid data format.
```

##### System information

Mitmproxy: 3.0.0.dev1101 (commit d9d4d15) binary
Python: 3.5.2
OpenSSL: OpenSSL 1.1.0g 2 Nov 2017
Platform: Linux-4.4.0-104-generic-x86_64-with-debian-stretch-sid



Discussion:

Resolving patch:
diff --git a/mitmproxy/addons/view.py b/mitmproxy/addons/view.py
--- a/mitmproxy/addons/view.py
+++ b/mitmproxy/addons/view.py
@@ -365,7 +365,8 @@ def load_file(self, path: mitmproxy.types.Path) -> None:
                     self.add([i.copy()])
         except IOError as e:
             ctx.log.error(e.strerror)
-            return
+        except exceptions.FlowReadException as e:
+            ctx.log.error(str(e))
 
     @command.command("view.go")
     def go(self, dst: int) -> None:


Test patch:
diff --git a/test/mitmproxy/addons/test_view.py b/test/mitmproxy/addons/test_view.py
--- a/test/mitmproxy/addons/test_view.py
+++ b/test/mitmproxy/addons/test_view.py
@@ -175,6 +175,10 @@ def test_load(tmpdir):
             v.load_file("nonexistent_file_path")
         except IOError:
             assert False
+        with open(path, "wb") as f:
+            f.write(b"invalidflows")
+        v.load_file(path)
+        assert tctx.master.has_log("Invalid data format.")
 
 
 def test_resolve():