coveralls: 
[![Coverage Status](https://coveralls.io/builds/2434186/badge)](https://coveralls.io/builds/2434186)

Coverage decreased (-0.2%) to 91.89% when pulling **53c06d00461e35cfd3ae9a27cecc7dcc9d0912f0 on sbc100:handle_errors** into **8c7840c8b835568116219e9d960764198add4927 on google:master**.

diff --git a/yapf/__init__.py b/yapf/__init__.py
index 7634c5c..7ffdfee 100644
--- a/yapf/__init__.py
+++ b/yapf/__init__.py
@@ -32,6 +32,7 @@ import logging
 import os
 import sys
 
+from yapf.yapflib import errors
 from yapf.yapflib import file_resources
 from yapf.yapflib import py3compat
 from yapf.yapflib import style
@@ -40,10 +41,6 @@ from yapf.yapflib import yapf_api
 __version__ = '0.1.7'
 
 
-class YapfError(Exception):
-  pass
-
-
 def main(argv):
   """Main program.
 
@@ -147,7 +144,7 @@ def main(argv):
 
   files = file_resources.GetCommandLineFiles(args.files, args.recursive)
   if not files:
-    raise YapfError('Input filenames did not match any python files')
+    raise errors.YapfError('Input filenames did not match any python files')
   FormatFiles(files, lines,
               style_config=args.style,
               no_local_style=args.no_local_style,
@@ -213,15 +210,19 @@ def _GetLines(line_strings):
     # The 'list' here is needed by Python 3.
     line = list(map(int, line_string.split('-', 1)))
     if line[0] < 1:
-      raise ValueError('invalid start of line range: %r' % line)
+      raise errors.YapfError('invalid start of line range: %r' % line)
     if line[0] > line[1]:
-      raise ValueError('end comes before start in line range: %r', line)
+      raise errors.YapfError('end comes before start in line range: %r', line)
     lines.append(tuple(line))
   return lines
 
 
 def run_main():  # pylint: disable=invalid-name
-  sys.exit(main(sys.argv))
+  try:
+    sys.exit(main(sys.argv))
+  except errors.YapfError as e:
+    sys.stderr.write('yapf: ' + str(e) + '\n')
+    sys.exit(1)
 
 
 if __name__ == '__main__':
diff --git a/yapf/yapflib/__init__.py b/yapf/yapflib/__init__.py
index e7522b2..f526bc3 100644
--- a/yapf/yapflib/__init__.py
+++ b/yapf/yapflib/__init__.py
@@ -11,3 +11,4 @@
 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 # See the License for the specific language governing permissions and
 # limitations under the License.
+
diff --git a/yapf/yapflib/errors.py b/yapf/yapflib/errors.py
new file mode 100644
index 0000000..1bf5bc7
--- /dev/null
+++ b/yapf/yapflib/errors.py
@@ -0,0 +1,22 @@
+# Copyright 2015 Google Inc. All Rights Reserved.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#     http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+
+class YapfError(Exception):
+  """Parent class for user errors or input errors.
+
+  Exceptions of this type are handled by the command line tool
+  and result in clear error messages, as opposed to backtraces.
+  """
+  pass
diff --git a/yapf/yapflib/style.py b/yapf/yapflib/style.py
index 7d1ecbb..518ace8 100644
--- a/yapf/yapflib/style.py
+++ b/yapf/yapflib/style.py
@@ -18,13 +18,10 @@ import re
 import textwrap
 
 from yapf.yapflib import py3compat
+from yapf.yapflib import errors
 
 
-class Error(Exception):
-  pass
-
-
-class StyleConfigError(Error):
+class StyleConfigError(errors.YapfError):
   """Raised when there's a problem reading the style configuration."""
   pass
 

yapf crashes with misggin style (e.g. --style=foo)
I've got a fix for this that I will send a PR for.

This is  the crash:
```
PYTHONPATH=$PWD/yapf python -m yapf --style=foo -i -r . 
Traceback (most recent call last):
  File "/usr/lib/python2.7/runpy.py", line 162, in _run_module_as_main
    "__main__", fname, loader, pkg_name)
  File "/usr/lib/python2.7/runpy.py", line 72, in _run_code
    exec code in run_globals
  File "/usr/local/google/home/sbc/dev/yapf/yapf/__main__.py", line 16, in <module>
    yapf.run_main()
  File "yapf/__init__.py", line 209, in run_main
    sys.exit(main(sys.argv))
  File "yapf/__init__.py", line 146, in main
    verify=args.verify)
  File "yapf/__init__.py", line 174, in FormatFiles
    print_diff=print_diff, verify=verify)
  File "yapf/yapflib/yapf_api.py", line 78, in FormatFile
    verify=verify), encoding
  File "yapf/yapflib/yapf_api.py", line 100, in FormatCode
    style.SetGlobalStyle(style.CreateStyleFromConfig(style_config))
  File "yapf/yapflib/style.py", line 212, in CreateStyleFromConfig
    config = _CreateConfigParserFromConfigFile(style_config)
  File "yapf/yapflib/style.py", line 234, in _CreateConfigParserFromConfigFile
    '"{0}" is not a valid style or file path'.format(config_filename))
yapf.yapflib.style.StyleConfigError: "foo" is not a valid style or file path
```

diff --git a/yapftests/main_test.py b/yapftests/main_test.py
index 314dcba..e216d67 100644
--- a/yapftests/main_test.py
+++ b/yapftests/main_test.py
@@ -57,10 +57,23 @@ def patched_input(code):
     yapf.py3compat.raw_input = raw_input
 
 
+class RunMainTest(unittest.TestCase):
+
+  def testShouldHandleYapfError(self):
+    """run_main should handle YapfError and sys.exit(1)"""
+    expected_message = 'yapf: Input filenames did not match any python files\n'
+    sys.argv = ['yapf', 'foo.c']
+    with captured_output() as (out, err):
+      with self.assertRaises(SystemExit):
+        ret = yapf.run_main()
+      self.assertEqual(out.getvalue(), '')
+      self.assertEqual(err.getvalue(), expected_message)
+
+
 class MainTest(unittest.TestCase):
 
   def testNoPythonFilesMatched(self):
-    with self.assertRaisesRegexp(yapf.YapfError,
+    with self.assertRaisesRegexp(yapf.errors.YapfError,
                                  'did not match any python files'):
       yapf.main(['yapf', 'foo.c'])
 

pip install -e .[dev]
parse_log_pytest
pytest
pytest
3.9
pytest --no-header -rA --tb=line --color=no -p no:cacheprovider -W ignore::DeprecationWarning
exceptiongroup @ file:///croot/exceptiongroup_1706031385326/work
iniconfig @ file:///home/linux1/recipes/ci/iniconfig_1610983019677/work
packaging @ file:///croot/packaging_1734472117206/work
pluggy @ file:///croot/pluggy_1733169602837/work
pytest @ file:///croot/pytest_1738938843180/work
tomli @ file:///opt/conda/conda-bld/tomli_1657175507142/work
-e git+https://github.com/google/yapf.git@5e7c8aadfe6ed7d892e858b305ef2ca60c65bfcc#egg=yapf

name: yapf
channels:
  - defaults
  - https://repo.anaconda.com/pkgs/main
  - https://repo.anaconda.com/pkgs/r
  - conda-forge
dependencies:
  - _libgcc_mutex=0.1=main
  - _openmp_mutex=5.1=1_gnu
  - ca-certificates=2025.2.25=h06a4308_0
  - exceptiongroup=1.2.0=py39h06a4308_0
  - iniconfig=1.1.1=pyhd3eb1b0_0
  - ld_impl_linux-64=2.40=h12ee557_0
  - libffi=3.4.4=h6a678d5_1
  - libgcc-ng=11.2.0=h1234567_1
  - libgomp=11.2.0=h1234567_1
  - libstdcxx-ng=11.2.0=h1234567_1
  - ncurses=6.4=h6a678d5_0
  - openssl=3.0.16=h5eee18b_0
  - packaging=24.2=py39h06a4308_0
  - pip=25.0=py39h06a4308_0
  - pluggy=1.5.0=py39h06a4308_0
  - pytest=8.3.4=py39h06a4308_0
  - python=3.9.21=he870216_1
  - readline=8.2=h5eee18b_0
  - setuptools=75.8.0=py39h06a4308_0
  - sqlite=3.45.3=h5eee18b_0
  - tk=8.6.14=h39e8969_0
  - tomli=2.0.1=py39h06a4308_0
  - tzdata=2025a=h04d1e81_0
  - wheel=0.45.1=py39h06a4308_0
  - xz=5.6.4=h5eee18b_1
  - zlib=1.2.13=h5eee18b_1
prefix: /opt/conda/envs/yapf

yapftests/main_test.py::RunMainTest::testShouldHandleYapfError yapftests/main_test.py::MainTest::testNoPythonFilesMatched
yapftests/main_test.py::MainTest::testEchoBadInput yapftests/main_test.py::MainTest::testEchoInput yapftests/main_test.py::MainTest::testEchoInputWithStyle yapftests/main_test.py::MainTest::testHelp yapftests/main_test.py::MainTest::testVersion
yapf/yapflib/__init__.py yapf/yapflib/errors.py yapf/__init__.py yapf/yapflib/style.py
yapf/yapflib/__init__.py yapf/yapflib/errors.py yapf/__init__.py yapf/yapflib/style.py