Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

daemon: fix /v2/snaps "Internal Server Error" error when installing unknown snaps #12945

Merged
merged 2 commits into from
Jul 18, 2023

Conversation

ZeyadYasser
Copy link
Collaborator

Fixes: https://bugs.launchpad.net/snapd/+bug/2024858

Internal Server Error response was returned when only one of many snaps is not found. The problem was passing all snap names (including successful ones) to errToResponse instead of the unknown snap only.

How to reproduce:
In the following example only "spamandeggs" is not found, 404 status code is expected, 500 is returned instead:

curl -sS --unix-socket /run/snapd.socket http://localhost/v2/snaps -X POST \
-d '{"action": "install", "snaps": ["spamandeggs", "hello"]}' -H "Content-Type: application/json" \
| jq
{
  "type": "error",
  "status-code": 500,
  "status": "Internal Server Error",
  "result": {
    "message": "store.SnapNotFound with 2 snaps"
  }
}

Side note:
When multiple snaps are unknown, generic BadRequest 400 is returned (where 404 would be preferable). This is due to the implementation of func (e SnapActionError) SingleOpError() checking that only a single error exists and not single error type exists (e.g. ErrSnapNotFound).
The logic for grouping single type errors already exists here and can be extracted into a reusable function.

curl -sS --unix-socket /run/snapd.socket http://localhost/v2/snaps -X POST \
-d '{"action": "install", "snaps": ["spamandeggs", "spamandeggs2"]}' -H "Content-Type: application/json" \
| jq
{
  "type": "error",
  "status-code": 400,
  "status": "Bad Request",
  "result": {
    "message": "cannot install \"snapandeggs\", \"spamandeggs2\": cannot install: snap not found: \"snapandeggs\", \"spamandeggs2\""
  }
}

…nknown snaps

Internal Server Error response was returned when only one of many snaps is
not found. The problem was passing all snap names (including succesful ones)
to errToResponse instead of the unknown snap only.

In the following example only "spamandeggs" is not found, 404 status code is
expected, 500 is returned instead:
curl -sS --unix-socket /run/snapd.socket http://localhost/v2/snaps -X POST \
-d '{"action": "install", "snaps": ["spamandeggs", "hello"]}' -H "Content-Type: application/json" \
| jq
> {
>   "type": "error",
>   "status-code": 500,
>   "status": "Internal Server Error",
>   "result": {
>     "message": "store.SnapNotFound with 2 snaps"
>   }
> }

Fixes: https://bugs.launchpad.net/snapd/+bug/2024858

Signed-off-by: Zeyad Gouda <zeyad.gouda@canonical.com>
@github-actions github-actions bot added the Needs Documentation -auto- Label automatically added which indicates the change needs documentation label Jul 4, 2023
@ZeyadYasser ZeyadYasser added Simple 😃 A small PR which can be reviewed quickly Skip spread Indicate that spread job should not run and removed Needs Documentation -auto- Label automatically added which indicates the change needs documentation labels Jul 4, 2023
@ZeyadYasser ZeyadYasser marked this pull request as ready for review July 4, 2023 09:49
@ZeyadYasser ZeyadYasser closed this Jul 4, 2023
@ZeyadYasser ZeyadYasser reopened this Jul 4, 2023
@github-actions github-actions bot added the Needs Documentation -auto- Label automatically added which indicates the change needs documentation label Jul 4, 2023
Copy link
Contributor

@MiguelPires MiguelPires left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The fix looks good, thanks for this. We need a unit test for it as well. Maybe there's even already a test that can be modified/fixed.
Also since this is production code (and not just a change to comments or something like that), the spread tests need to run. I'll close and re-open to trigger them

@MiguelPires MiguelPires removed the Skip spread Indicate that spread job should not run label Jul 4, 2023
@MiguelPires MiguelPires closed this Jul 4, 2023
@MiguelPires MiguelPires reopened this Jul 4, 2023
This modification is needed to test the edge case of having one snap
failing with ErrSnapNotFound and another snap being successful.
It used to return 500 error instead of the more useful 404.

For context see: https://bugs.launchpad.net/snapd/+bug/2024858

Signed-off-by: Zeyad Gouda <zeyad.gouda@canonical.com>
@@ -154,33 +154,41 @@ func (s *errorsSuite) TestErrToResponse(c *C) {
tests := []struct {
err error
expectedRsp daemon.Response
isMany bool
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Unit test TestErrToResponse is now updated.
I thought of adding a snaps array instead of the isMany flag for more flexibility in the test, but it seemed very verbose and not necessary. Would love to hear your opinion.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think it's fine like this. The array would probably remove the need to have the if in the test and support other test cases but for now I think this is good

@codecov-commenter
Copy link

Codecov Report

Merging #12945 (15774f3) into master (b0c8a48) will decrease coverage by 0.01%.
The diff coverage is 100.00%.

❗ Your organization is not using the GitHub App Integration. As a result you may experience degraded service beginning May 15th. Please install the Github App Integration for your organization. Read more.

@@            Coverage Diff             @@
##           master   #12945      +/-   ##
==========================================
- Coverage   78.61%   78.61%   -0.01%     
==========================================
  Files         995      995              
  Lines      123514   123514              
==========================================
- Hits        97102    97099       -3     
- Misses      20285    20287       +2     
- Partials     6127     6128       +1     
Flag Coverage Δ
unittests 78.61% <100.00%> (-0.01%) ⬇️

Flags with carried forward coverage won't be shown. Click here to find out more.

Impacted Files Coverage Δ
daemon/errors.go 98.27% <100.00%> (ø)

... and 4 files with indirect coverage changes

📣 We’re building smart automated test selection to slash your CI/CD build times. Learn more

Copy link
Contributor

@MiguelPires MiguelPires left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM, thanks

Copy link
Member

@olivercalder olivercalder left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM, thank you! I was confused by the recursive errToResponse() call (hence the delay in review), but I understand what's going on now. Your changes look great!

Copy link
Collaborator

@pedronis pedronis left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

+1

@pedronis pedronis merged commit 9431b3f into snapcore:master Jul 18, 2023
50 of 52 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Needs Documentation -auto- Label automatically added which indicates the change needs documentation Simple 😃 A small PR which can be reviewed quickly
Projects
None yet
5 participants