prompt: We are currently solving the following issue within our repository. Here is the issue text:
  --- BEGIN ISSUE ---
  Providing a non-existing argument should fail gracefully
  ## Problem Definition
  
  When a non-existing argument is provided to rotkehlchen at the moment  an exception is thrown.
  
  ```
  __main__.py: error: unrecognized arguments: --lol                                                                                                                                                                                                                               
  CRITICAL:root:Traceback (most recent call last):                                                                                                                                                                                                                                
    File "/home/lefteris/w/rotkehlchen/rotkehlchen/__main__.py", line 12, in main
      rotkehlchen_server = RotkehlchenServer()
    File "/home/lefteris/w/rotkehlchen/rotkehlchen/server.py", line 25, in __init__
      self.args = app_args()
    File "/home/lefteris/w/rotkehlchen/rotkehlchen/args.py", line 91, in app_args
      args = p.parse_args()
    File "/usr/lib64/python3.7/argparse.py", line 1752, in parse_args
      self.error(msg % ' '.join(argv))
    File "/usr/lib64/python3.7/argparse.py", line 2501, in error
      self.exit(2, _('%(prog)s: error: %(message)s\n') % args)
    File "/usr/lib64/python3.7/argparse.py", line 2488, in exit
      _sys.exit(status)
  SystemExit: 2
  ```
  
  
  
  ## Task
  
  Instead of throwing an exception, an error message should be displayed and the program should exit gracefully.
  
  --- END ISSUE ---
  
  Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
  --- BEGIN FILES ---
  Path: `rotkehlchen/__main__.py`
  Content:
  ```
  1 from gevent import monkey
  2 monkey.patch_all()
  3 import logging
  4 logger = logging.getLogger(__name__)
  5 
  6 
  7 def main():
  8     import traceback
  9     import sys
  10     from rotkehlchen.server import RotkehlchenServer
  11     try:
  12         rotkehlchen_server = RotkehlchenServer()
  13     except SystemExit as e:
  14         if e.code is None or e.code == 0:
  15             sys.exit(0)
  16         else:
  17             tb = traceback.format_exc()
  18             logging.critical(tb)
  19             print("Failed to start rotkehlchen backend:\n{}".format(tb))
  20             sys.exit(1)
  21     except: # noqa
  22         tb = traceback.format_exc()
  23         logging.critical(tb)
  24         print("Failed to start rotkehlchen backend:\n{}".format(tb))
  25         sys.exit(1)
  26 
  27     rotkehlchen_server.main()
  28 
  29 
  30 if __name__ == '__main__':
  31     main()
  32
  ```
  
  Path: `rotkehlchen/args.py`
  Content:
  ```
  1 #!/usr/bin/env python
  2 import argparse
  3 from rotkehlchen.config import default_data_directory
  4 
  5 
  6 def app_args() -> argparse.Namespace:
  7     """ Parse the arguments and create and return the arguments object"""
  8     p = argparse.ArgumentParser(description='Rotkehlchen Crypto Portfolio Management')
  9 
  10     p.add_argument(
  11         '--output',
  12         help=(
  13             'A path to a file for logging all output. If nothing is given'
  14             'stdout is used'
  15         )
  16     )
  17     p.add_argument(
  18         '--sleep-secs',
  19         type=int,
  20         default=20,
  21         help="Seconds to sleep during the main loop"
  22     )
  23     p.add_argument(
  24         '--notify',
  25         action='store_true',
  26         help=(
  27             'If given then the tool will send notifications via '
  28             'notify-send.'
  29         )
  30     )
  31     p.add_argument(
  32         '--data-dir',
  33         help='The directory where all data and configs are placed',
  34         default=default_data_directory()
  35     )
  36     p.add_argument(
  37         '--zerorpc-port',
  38         help='The port on which to open a zerorpc server for communication with the UI',
  39         default=4242
  40     )
  41     p.add_argument(
  42         '--ethrpc-port',
  43         help="The port on which to communicate with an ethereum client's RPC.",
  44         default=8545,
  45     )
  46     p.add_argument(
  47         '--logfile',
  48         help='The name of the file to write log entries to',
  49         default='rotkehlchen.log',
  50     )
  51     p.add_argument(
  52         '--logtarget',
  53         help='Choose where logging entries will be sent. Valid values are "file and "stdout"',
  54         choices=['stdout', 'file'],
  55         default='file',
  56     )
  57     p.add_argument(
  58         '--loglevel',
  59         help='Choose the logging level',
  60         choices=['debug', 'info', 'warn', 'error', 'critical'],
  61         default='debug'
  62     )
  63     p.add_argument(
  64         '--logfromothermodules',
  65         help=(
  66             'If given then logs from all imported modules that use the '
  67             'logging system will also be visible.'
  68         ),
  69         action='store_true',
  70     )
  71 
  72     args = p.parse_args()
  73 
  74     return args
  75
  ```
  --- END FILES ---
  
  Please first localize the bug based on the issue statement, and then generate a patch according to the `git diff` format fenced by three backticks.
  
  Here is an example:
  
  ```diff
  diff --git a/examples/server_async.py b/examples/server_async.py
  --- a/examples/server_async.py
  +++ b/examples/server_async.py
  @@ -313,4 +313,4 @@
   
   
   if __name__ == "__main__":
  -    asyncio.run(run_async_server("."), debug=True)
  +    asyncio.run(run_async_server(), debug=True)
  diff --git a/examples/server_sync.py b/examples/server_sync.py
  --- a/examples/server_sync.py
  +++ b/examples/server_sync.py
  @@ -313,5 +313,5 @@
   
   
   if __name__ == "__main__":
  -    server = run_sync_server(".")
  +    server = run_sync_server()
       server.shutdown()
  
  ```
  
golden_diff: diff --git a/rotkehlchen/__main__.py b/rotkehlchen/__main__.py
  --- a/rotkehlchen/__main__.py
  +++ b/rotkehlchen/__main__.py
  @@ -1,6 +1,8 @@
  +import logging
  +
   from gevent import monkey
  +
   monkey.patch_all()
  -import logging
   logger = logging.getLogger(__name__)
   
   
  @@ -11,8 +13,10 @@
       try:
           rotkehlchen_server = RotkehlchenServer()
       except SystemExit as e:
  -        if e.code is None or e.code == 0:
  -            sys.exit(0)
  +        if e.code is None or e.code == 0 or e.code == 2:
  +            # exit_code 2 is for invalid arguments
  +            exit_code = 0 if e.code is None else e.code
  +            sys.exit(exit_code)
           else:
               tb = traceback.format_exc()
               logging.critical(tb)
  diff --git a/rotkehlchen/args.py b/rotkehlchen/args.py
  --- a/rotkehlchen/args.py
  +++ b/rotkehlchen/args.py
  @@ -1,11 +1,28 @@
   #!/usr/bin/env python
   import argparse
  +import sys
  +
   from rotkehlchen.config import default_data_directory
  +from rotkehlchen.utils import get_system_spec
  +
  +
  +class VersionAction(argparse.Action):
  +    def __init__(self, option_strings, dest, nargs=None, required=False, **kwargs):
  +        if nargs is not None:
  +            raise ValueError("nargs not allowed")
  +        super().__init__(option_strings, dest, **kwargs)
  +
  +    def __call__(self, parser, namespace, values, option_string=None):
  +        print(get_system_spec()['rotkehlchen'])
  +        sys.exit(0)
   
   
   def app_args() -> argparse.Namespace:
       """ Parse the arguments and create and return the arguments object"""
  -    p = argparse.ArgumentParser(description='Rotkehlchen Crypto Portfolio Management')
  +    p = argparse.ArgumentParser(
  +        prog='rotkehlchen',
  +        description='Rotkehlchen Crypto Portfolio Management',
  +    )
   
       p.add_argument(
           '--output',
  @@ -68,6 +85,11 @@
           ),
           action='store_true',
       )
  +    p.add_argument(
  +        'version',
  +        help='Shows the rotkehlchen version',
  +        action=VersionAction,
  +    )
   
       args = p.parse_args()
  
verification_info: {"golden_diff": "diff --git a/rotkehlchen/__main__.py b/rotkehlchen/__main__.py\n--- a/rotkehlchen/__main__.py\n+++ b/rotkehlchen/__main__.py\n@@ -1,6 +1,8 @@\n+import logging\n+\n from gevent import monkey\n+\n monkey.patch_all()\n-import logging\n logger = logging.getLogger(__name__)\n \n \n@@ -11,8 +13,10 @@\n     try:\n         rotkehlchen_server = RotkehlchenServer()\n     except SystemExit as e:\n-        if e.code is None or e.code == 0:\n-            sys.exit(0)\n+        if e.code is None or e.code == 0 or e.code == 2:\n+            # exit_code 2 is for invalid arguments\n+            exit_code = 0 if e.code is None else e.code\n+            sys.exit(exit_code)\n         else:\n             tb = traceback.format_exc()\n             logging.critical(tb)\ndiff --git a/rotkehlchen/args.py b/rotkehlchen/args.py\n--- a/rotkehlchen/args.py\n+++ b/rotkehlchen/args.py\n@@ -1,11 +1,28 @@\n #!/usr/bin/env python\n import argparse\n+import sys\n+\n from rotkehlchen.config import default_data_directory\n+from rotkehlchen.utils import get_system_spec\n+\n+\n+class VersionAction(argparse.Action):\n+    def __init__(self, option_strings, dest, nargs=None, required=False, **kwargs):\n+        if nargs is not None:\n+            raise ValueError(\"nargs not allowed\")\n+        super().__init__(option_strings, dest, **kwargs)\n+\n+    def __call__(self, parser, namespace, values, option_string=None):\n+        print(get_system_spec()['rotkehlchen'])\n+        sys.exit(0)\n \n \n def app_args() -> argparse.Namespace:\n     \"\"\" Parse the arguments and create and return the arguments object\"\"\"\n-    p = argparse.ArgumentParser(description='Rotkehlchen Crypto Portfolio Management')\n+    p = argparse.ArgumentParser(\n+        prog='rotkehlchen',\n+        description='Rotkehlchen Crypto Portfolio Management',\n+    )\n \n     p.add_argument(\n         '--output',\n@@ -68,6 +85,11 @@\n         ),\n         action='store_true',\n     )\n+    p.add_argument(\n+        'version',\n+        help='Shows the rotkehlchen version',\n+        action=VersionAction,\n+    )\n \n     args = p.parse_args()\n", "issue": "Providing a non-existing argument should fail gracefully\n## Problem Definition\r\n\r\nWhen a non-existing argument is provided to rotkehlchen at the moment  an exception is thrown.\r\n\r\n```\r\n__main__.py: error: unrecognized arguments: --lol                                                                                                                                                                                                                               \r\nCRITICAL:root:Traceback (most recent call last):                                                                                                                                                                                                                                \r\n  File \"/home/lefteris/w/rotkehlchen/rotkehlchen/__main__.py\", line 12, in main\r\n    rotkehlchen_server = RotkehlchenServer()\r\n  File \"/home/lefteris/w/rotkehlchen/rotkehlchen/server.py\", line 25, in __init__\r\n    self.args = app_args()\r\n  File \"/home/lefteris/w/rotkehlchen/rotkehlchen/args.py\", line 91, in app_args\r\n    args = p.parse_args()\r\n  File \"/usr/lib64/python3.7/argparse.py\", line 1752, in parse_args\r\n    self.error(msg % ' '.join(argv))\r\n  File \"/usr/lib64/python3.7/argparse.py\", line 2501, in error\r\n    self.exit(2, _('%(prog)s: error: %(message)s\\n') % args)\r\n  File \"/usr/lib64/python3.7/argparse.py\", line 2488, in exit\r\n    _sys.exit(status)\r\nSystemExit: 2\r\n```\r\n\r\n\r\n\r\n## Task\r\n\r\nInstead of throwing an exception, an error message should be displayed and the program should exit gracefully.\n", "before_files": [{"content": "from gevent import monkey\nmonkey.patch_all()\nimport logging\nlogger = logging.getLogger(__name__)\n\n\ndef main():\n    import traceback\n    import sys\n    from rotkehlchen.server import RotkehlchenServer\n    try:\n        rotkehlchen_server = RotkehlchenServer()\n    except SystemExit as e:\n        if e.code is None or e.code == 0:\n            sys.exit(0)\n        else:\n            tb = traceback.format_exc()\n            logging.critical(tb)\n            print(\"Failed to start rotkehlchen backend:\\n{}\".format(tb))\n            sys.exit(1)\n    except: # noqa\n        tb = traceback.format_exc()\n        logging.critical(tb)\n        print(\"Failed to start rotkehlchen backend:\\n{}\".format(tb))\n        sys.exit(1)\n\n    rotkehlchen_server.main()\n\n\nif __name__ == '__main__':\n    main()\n", "path": "rotkehlchen/__main__.py"}, {"content": "#!/usr/bin/env python\nimport argparse\nfrom rotkehlchen.config import default_data_directory\n\n\ndef app_args() -> argparse.Namespace:\n    \"\"\" Parse the arguments and create and return the arguments object\"\"\"\n    p = argparse.ArgumentParser(description='Rotkehlchen Crypto Portfolio Management')\n\n    p.add_argument(\n        '--output',\n        help=(\n            'A path to a file for logging all output. If nothing is given'\n            'stdout is used'\n        )\n    )\n    p.add_argument(\n        '--sleep-secs',\n        type=int,\n        default=20,\n        help=\"Seconds to sleep during the main loop\"\n    )\n    p.add_argument(\n        '--notify',\n        action='store_true',\n        help=(\n            'If given then the tool will send notifications via '\n            'notify-send.'\n        )\n    )\n    p.add_argument(\n        '--data-dir',\n        help='The directory where all data and configs are placed',\n        default=default_data_directory()\n    )\n    p.add_argument(\n        '--zerorpc-port',\n        help='The port on which to open a zerorpc server for communication with the UI',\n        default=4242\n    )\n    p.add_argument(\n        '--ethrpc-port',\n        help=\"The port on which to communicate with an ethereum client's RPC.\",\n        default=8545,\n    )\n    p.add_argument(\n        '--logfile',\n        help='The name of the file to write log entries to',\n        default='rotkehlchen.log',\n    )\n    p.add_argument(\n        '--logtarget',\n        help='Choose where logging entries will be sent. Valid values are \"file and \"stdout\"',\n        choices=['stdout', 'file'],\n        default='file',\n    )\n    p.add_argument(\n        '--loglevel',\n        help='Choose the logging level',\n        choices=['debug', 'info', 'warn', 'error', 'critical'],\n        default='debug'\n    )\n    p.add_argument(\n        '--logfromothermodules',\n        help=(\n            'If given then logs from all imported modules that use the '\n            'logging system will also be visible.'\n        ),\n        action='store_true',\n    )\n\n    args = p.parse_args()\n\n    return args\n", "path": "rotkehlchen/args.py"}], "after_files": [{"content": "import logging\n\nfrom gevent import monkey\n\nmonkey.patch_all()\nlogger = logging.getLogger(__name__)\n\n\ndef main():\n    import traceback\n    import sys\n    from rotkehlchen.server import RotkehlchenServer\n    try:\n        rotkehlchen_server = RotkehlchenServer()\n    except SystemExit as e:\n        if e.code is None or e.code == 0 or e.code == 2:\n            # exit_code 2 is for invalid arguments\n            exit_code = 0 if e.code is None else e.code\n            sys.exit(exit_code)\n        else:\n            tb = traceback.format_exc()\n            logging.critical(tb)\n            print(\"Failed to start rotkehlchen backend:\\n{}\".format(tb))\n            sys.exit(1)\n    except: # noqa\n        tb = traceback.format_exc()\n        logging.critical(tb)\n        print(\"Failed to start rotkehlchen backend:\\n{}\".format(tb))\n        sys.exit(1)\n\n    rotkehlchen_server.main()\n\n\nif __name__ == '__main__':\n    main()\n", "path": "rotkehlchen/__main__.py"}, {"content": "#!/usr/bin/env python\nimport argparse\nimport sys\n\nfrom rotkehlchen.config import default_data_directory\nfrom rotkehlchen.utils import get_system_spec\n\n\nclass VersionAction(argparse.Action):\n    def __init__(self, option_strings, dest, nargs=None, required=False, **kwargs):\n        if nargs is not None:\n            raise ValueError(\"nargs not allowed\")\n        super().__init__(option_strings, dest, **kwargs)\n\n    def __call__(self, parser, namespace, values, option_string=None):\n        print(get_system_spec()['rotkehlchen'])\n        sys.exit(0)\n\n\ndef app_args() -> argparse.Namespace:\n    \"\"\" Parse the arguments and create and return the arguments object\"\"\"\n    p = argparse.ArgumentParser(\n        prog='rotkehlchen',\n        description='Rotkehlchen Crypto Portfolio Management',\n    )\n\n    p.add_argument(\n        '--output',\n        help=(\n            'A path to a file for logging all output. If nothing is given'\n            'stdout is used'\n        )\n    )\n    p.add_argument(\n        '--sleep-secs',\n        type=int,\n        default=20,\n        help=\"Seconds to sleep during the main loop\"\n    )\n    p.add_argument(\n        '--notify',\n        action='store_true',\n        help=(\n            'If given then the tool will send notifications via '\n            'notify-send.'\n        )\n    )\n    p.add_argument(\n        '--data-dir',\n        help='The directory where all data and configs are placed',\n        default=default_data_directory()\n    )\n    p.add_argument(\n        '--zerorpc-port',\n        help='The port on which to open a zerorpc server for communication with the UI',\n        default=4242\n    )\n    p.add_argument(\n        '--ethrpc-port',\n        help=\"The port on which to communicate with an ethereum client's RPC.\",\n        default=8545,\n    )\n    p.add_argument(\n        '--logfile',\n        help='The name of the file to write log entries to',\n        default='rotkehlchen.log',\n    )\n    p.add_argument(\n        '--logtarget',\n        help='Choose where logging entries will be sent. Valid values are \"file and \"stdout\"',\n        choices=['stdout', 'file'],\n        default='file',\n    )\n    p.add_argument(\n        '--loglevel',\n        help='Choose the logging level',\n        choices=['debug', 'info', 'warn', 'error', 'critical'],\n        default='debug'\n    )\n    p.add_argument(\n        '--logfromothermodules',\n        help=(\n            'If given then logs from all imported modules that use the '\n            'logging system will also be visible.'\n        ),\n        action='store_true',\n    )\n    p.add_argument(\n        'version',\n        help='Shows the rotkehlchen version',\n        action=VersionAction,\n    )\n\n    args = p.parse_args()\n\n    return args\n", "path": "rotkehlchen/args.py"}]}