I think lein ancient upgrade should have non-zero exit code when the tests fail.
Currently what happens is that the test-failing code goes through leiningen.core.main/exit with the flag set causing that method to throw an exception rather than exit, and the exception gets printed somehow, and the process exits with exit code 0.