diff --git a/shub/login.py b/shub/login.py
index af5f8aa..4699e07 100644
--- a/shub/login.py
+++ b/shub/login.py
@@ -10,7 +10,8 @@ from six.moves import input
 @click.pass_context
 def cli(context):
     if auth.get_key_netrc():
-        context.fail('Already logged in. To logout use: shub logout')
+        log("You're already logged in. To change credentials, use 'shub logout' first.")
+        return 0
 
     cfg_key = _find_cfg_key()
     key = _prompt_for_key(suggestion=cfg_key)

login while already logged-in shows error
If one is already logged in, `shub login` throws an error, while it could say something less "dramatic"

Current behavior:

```
$ shub login
Usage: shub login [OPTIONS]

Error: Already logged in. To logout use: shub logout
```

- no need to show "Usage" as it's correct
- "Error" is misleading. it could say "You're already logged in. Nothing to do. If you want to login with another API key, use `logout` first", or something along those lines
diff --git a/tests/test_login.py b/tests/test_login.py
index 48ba3b9..00c195e 100644
--- a/tests/test_login.py
+++ b/tests/test_login.py
@@ -65,3 +65,17 @@ username = KEY_SUGGESTION
 
             # then
             self.assertEqual(0, result.exit_code, result.exception)
+
+    def test_login_attempt_after_login_doesnt_lead_to_an_error(self):
+        with self.runner.isolated_filesystem() as fs:
+            login.auth.NETRC_FILE = os.path.join(fs, '.netrc')
+
+            # given
+            self.runner.invoke(login.cli, input=self.VALID_KEY)
+
+            # when
+            result = self.runner.invoke(login.cli, input=self.VALID_KEY)
+
+            # then
+            self.assertEqual(0, result.exit_code)
+            self.assertTrue('already logged in' in result.output)

pip install -e .
parse_log_pytest
requirements.txt
pytest mock scrapy
apt-get update apt-get install -y gcc
3.9
requirements.txt
pytest --no-header -rA --tb=line --color=no -p no:cacheprovider -W ignore::DeprecationWarning
attrs==25.3.0
Automat==24.8.1
certifi==2025.1.31
cffi==1.17.1
charset-normalizer==3.4.1
click==8.1.8
constantly==23.10.4
cryptography==44.0.2
cssselect==1.3.0
defusedxml==0.7.1
exceptiongroup==1.2.2
filelock==3.18.0
hyperlink==21.0.0
idna==3.10
incremental==24.7.2
iniconfig==2.1.0
itemadapter==0.11.0
itemloaders==1.3.2
jmespath==1.0.1
lxml==5.3.1
mock==5.2.0
packaging==24.2
parsel==1.10.0
pluggy==1.5.0
Protego==0.4.0
pyasn1==0.6.1
pyasn1_modules==0.4.2
pycparser==2.22
PyDispatcher==2.0.7
pyOpenSSL==25.0.0
pytest==8.3.5
queuelib==1.7.0
requests==2.32.3
requests-file==2.1.0
Scrapy==2.12.0
service-identity==24.2.0
-e git+https://github.com/scrapinghub/shub.git@7d6eb64b6bfa5de78f20629bfd92922489bd187d#egg=shub
six==1.17.0
tldextract==5.1.3
tomli==2.2.1
Twisted==24.11.0
typing_extensions==4.13.0
urllib3==2.3.0
w3lib==2.3.1
zope.interface==7.2

name: shub
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
  - 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
  - pip=25.0=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
  - tzdata=2025a=h04d1e81_0
  - wheel=0.45.1=py39h06a4308_0
  - xz=5.6.4=h5eee18b_1
  - zlib=1.2.13=h5eee18b_1
  - pip:
      - attrs==25.3.0
      - automat==24.8.1
      - certifi==2025.1.31
      - cffi==1.17.1
      - charset-normalizer==3.4.1
      - click==8.1.8
      - constantly==23.10.4
      - cryptography==44.0.2
      - cssselect==1.3.0
      - defusedxml==0.7.1
      - exceptiongroup==1.2.2
      - filelock==3.18.0
      - hyperlink==21.0.0
      - idna==3.10
      - incremental==24.7.2
      - iniconfig==2.1.0
      - itemadapter==0.11.0
      - itemloaders==1.3.2
      - jmespath==1.0.1
      - lxml==5.3.1
      - mock==5.2.0
      - packaging==24.2
      - parsel==1.10.0
      - pluggy==1.5.0
      - protego==0.4.0
      - pyasn1==0.6.1
      - pyasn1-modules==0.4.2
      - pycparser==2.22
      - pydispatcher==2.0.7
      - pyopenssl==25.0.0
      - pytest==8.3.5
      - queuelib==1.7.0
      - requests==2.32.3
      - requests-file==2.1.0
      - scrapy==2.12.0
      - service-identity==24.2.0
      - six==1.17.0
      - tldextract==5.1.3
      - tomli==2.2.1
      - twisted==24.11.0
      - typing-extensions==4.13.0
      - urllib3==2.3.0
      - w3lib==2.3.1
      - zope-interface==7.2
prefix: /opt/conda/envs/shub

tests/test_login.py::LoginTest::test_login_attempt_after_login_doesnt_lead_to_an_error
tests/test_login.py::LoginTest::test_login_can_handle_invalid_scrapy_cfg tests/test_login.py::LoginTest::test_login_suggests_scrapy_cfg_username_as_key tests/test_login.py::LoginTest::test_login_suggests_shub_apikey_as_key tests/test_login.py::LoginTest::test_login_validates_api_key tests/test_login.py::LoginTest::test_login_writes_input_key_to_netrc_file
shub/login.py
shub/login.py