Repository navigation
fix: tell the user why NUITEQ refused, not which request it refused - #75
Merged
Merged
Conversation
oleksandr-nc
force-pushed
the
fix/nuiteq-api-errors
branch
7 times, most recently
from
October 21, 2026 08:52
8bd86a6 to
9d89f81
Compare
NUITEQ answers an unknown username and password with a 401 and its
reason, {"error":"Invalid username or password"}. Nextcloud's client
throws on an answer of 400 or above, and for every refusal but a 403
with a JSON object or array, both login() and request() handed back the
exception's own message instead. That is Guzzle's English, naming the
request that failed, so that login showed in the personal settings as
Client error: `POST https://nuiteqstage.se/api/v1/login` resulted
in a `401 Unauthorized` response:
{"error":"Invalid username or password"}
The settings after a login, and the toasts after listing, creating and
deleting boards, now show NUITEQ's reason, the error of its JSON answer,
when it gives one, and otherwise the status: "Login failed: the NUITEQ
Stage URL answered 401" or "The NUITEQ Stage URL answered 500". Without
NUITEQ's reason a 401 or a 403 may come from a proxy or a firewall, so
it is not told as a verdict on the credentials. The exception's message
goes to the log, where the URL and the status are worth having.
A 403 with a JSON object or array as its body was handed back as NUITEQ
wrote it. The 403 NUITEQ answers a key it does not know with carries an
error, so it was handed back as a refusal. Without one, a deletion
NUITEQ refused read as success and took the board off the list. It is a
refusal like any other now.
The catch blocks are tested with the exceptions Guzzle itself builds,
whose message is the one Nextcloud's client carries and the log now
reads. A clone on its own has no Guzzle, so it is a dev dependency of
the tests; CI runs them inside a server checkout, which ships Guzzle
itself. Psalm finds Guzzle's classes in vendor/ now, so the
UndefinedClass suppression for them suppresses nothing, which psalm
reports as an error. The two classes beside them are ones nothing in
lib/ refers to, so the suppression goes whole.
Signed-off-by: Oleksander Piskun <oleksandr2088@icloud.com>
oleksandr-nc
force-pushed
the
fix/nuiteq-api-errors
branch
from
October 21, 2026 09:11
9d89f81 to
bdf4922
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Follow-up to #71 and #74, after which the toasts for listing, creating and deleting boards, and those of the settings, show whatever reason the server hands back. For a request NUITEQ refused, that reason was Guzzle's message naming the request, unless the refusal was a 403 with a JSON object or array.
A refused login showed the request that failed
NUITEQ answers an unknown username and password with a 401 and its reason,
{"error":"Invalid username or password"}. Nextcloud's client throws on an answer of 400 or above, and for every refusal but a 403 with a JSON object or array, bothlogin()andrequest()handed back the exception's own message instead: Guzzle's English, naming the request that failed. That login showed in the personal settings asThe settings after a login, and the toasts after listing, creating and deleting boards, now show NUITEQ's reason, the
errorof its JSON answer, when it gives one, and otherwise the status: "Login failed: the NUITEQ Stage URL answered 401" or "The NUITEQ Stage URL answered 500". Without NUITEQ's reason a 401 or a 403 may come from a proxy or a firewall, so it is not told as a verdict on the credentials. The exception's message goes to the log, where the URL and the status are worth having.A 403 without a reason is a refusal too
A 403 with a JSON object or array as its body was handed back as NUITEQ wrote it. The 403 NUITEQ answers a key it does not know with carries an
error, so it was handed back as a refusal. Without one, a deletion NUITEQ refused read as success and took the board off the list. It is a refusal like any other now.Guzzle is a dev dependency of the tests
The catch blocks are tested with the exceptions Guzzle itself builds, whose message is the one Nextcloud's client carries and the log now reads. A clone on its own has no Guzzle; CI runs the tests inside a server checkout, which ships Guzzle itself. Psalm finds Guzzle's classes in
vendor/now, so theUndefinedClasssuppression for them suppresses nothing, which psalm reports as an error. The two classes beside them are ones nothing inlib/refers to, so the suppression goes whole.🤖 AI (if applicable)