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

feat(deploy): Output plain text when Hippo login fails #647

Merged
merged 3 commits into from
Jul 25, 2022

Conversation

lidongjies
Copy link
Contributor

Signed-off-by: lidongjies lidongjies@gmail.com

With this PR, if it fails to obtain the Hippo token when executing the "spin deploy" command, the following error message will be output

Error: Problem login Hippo.

Caused by:
{"type":"https://tools.ietf.org/html/rfc7231#section-6.5.1","title":"Login failed.","status":400,"detail":"Login failed: "}

Related issue #614

Signed-off-by: lidongjies <lidongjies@gmail.com>
Copy link
Contributor

@itowlson itowlson left a comment

Choose a reason for hiding this comment

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

Thanks for tacking this! Unfortunately, we are ideally looking for a bit more than this - what I'm hoping for is to have the top level message reflect the error detail as well as indicating that it's Hippo. That said, I'm not sure what messages the Hippo client returns, and maybe we can't get anything more than "Login failed", in which case fair enough.

@@ -147,7 +147,8 @@ impl DeployCommand {
self.hippo_username.clone(),
self.hippo_password.clone(),
)
.await?
.await
.context("Problem login Hippo")?
Copy link
Contributor

Choose a reason for hiding this comment

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

A couple of things here:

  • First, and apologies for nit-picking the English here, but this should be phrased as something like "Problem logging into Hippo"
  • Second, it would be nice to extract the reason from the Hippo failure response and present that. What this does is address the second part of Deploy: raw JSON in output if Hippo login fails #614 (say that the error comes from Hippo rather than from Bindle), which is good, but the reason is still buried in the raw JSON. What I'd suggest is that we parse the JSON, look at either the title or detail elements (@bacongobbler can probably recommend which) and output that as part of the message. We can still dump the JSON, but this way we get a top-level message which is still precise but is also more readable.

Hope this makes sense, happy to discuss further!

@lidongjies
Copy link
Contributor Author

Thank you for your detailed reply, which is very helpful to me.

I have found the error handling department of the login method in Hippo cli, and I will handle the error information according to your suggestions.

https://github.com/deislabs/hippo-cli/blob/3d8a002a5041181f25e460d3fb1fe4e053881839/src/client.rs#L303-L319

@bacongobbler
Copy link
Member

bacongobbler commented Jul 18, 2022

format_response_error is meant more for API-level response errors in the form of a ValidationException, like when you're adding an App or a Channel to the API with malformed data.

I'd look at HandleLoginFailedException for implementation details as well as what's being returned in this scenario.

The error being returned by Hippo doesn't provide much context as to why the login failed, but I'd suggest parsing the title and description.

Signed-off-by: lidongjies <lidongjies@gmail.com>
@lidongjies
Copy link
Contributor Author

@itowlson

I have parsed JSON and displayed the 'detailed' field, because neither the 'title' nor the 'detailed' field indicates that the problem occurs in Hippo, so I keep 'problem login into Hippo'.

When using an unregistered Hippo username.

Error: Problem login into Hippo: Login failed: Account does not exist.

When Hippo password is incorrect.

Error: Problem login into Hippo: Login failed:

Copy link
Contributor

@itowlson itowlson left a comment

Choose a reason for hiding this comment

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

This looks good - thanks for addressing that! There's still one persnickety amendment to the grammar (for which I apologise, but it's user facing), and I also had a suggestion regarding the case where there's no detail. In substance it's spot on though - thanks again!

Ok(token_info) => token_info.token.unwrap_or_default(),
Err(err) => {
let error: LoginHippoError = serde_json::from_str(err.to_string().as_str())?;
bail!("Problem login into Hippo: {}", error.detail);
Copy link
Contributor

Choose a reason for hiding this comment

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

Minor grammar tweak:

Suggested change
bail!("Problem login into Hippo: {}", error.detail);
bail!("Problem logging into Hippo: {}", error.detail);

Copy link
Contributor

Choose a reason for hiding this comment

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

You note that if the password is incorrect, the detail is blank, so you end up with a trailing colon here (Problem logging into Hippo: ). I'd suggest checking for the empty string and dropping the colon (Problem logging into Hippo) so it looks a bit tidier in this case.

To avoid this making the Err clause so big that it derails the reading flow, you could hive this off into a helper function e.g.

Err(err) => bail!(format_login_error(err)?),

// ...

fn format_login_error(err: &Error) -> anyhow::Result<String> {
  let error: LoginHippoError = /* as you have it now */;
  if error.detail.is_empty() {
    // message without colon
  } else {
    // message with colon and detail
  }
}

Copy link
Contributor Author

@lidongjies lidongjies Jul 25, 2022

Choose a reason for hiding this comment

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

The detail field is not blank, and the trailing colon is part of the detail field.

When using an unregistered Hippo username.

{ "title": "Login failed.", "detail": "Login failed: Account does not exist." }

When Hippo password is incorrect.

{ "title": "Login failed.", "detail": "Login failed:" }

Copy link
Contributor Author

Choose a reason for hiding this comment

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

fn format_login_error(err: &anyhow::Error) -> anyhow::Result<String> {
    let error: LoginHippoError = serde_json::from_str(err.to_string().as_str())?;
    if error.detail.ends_with(": ") {
        Ok(format!(
            "Problem logging into Hippo: {}",
            error.detail.replace(": ", ".")
        ))
    } else {
        Ok(format!("Problem logging into Hippo: {}", error.detail))
    }
}

When using an unregistered Hippo username.

Error: Problem login into Hippo: Login failed: Account does not exist.

When Hippo password is incorrect.

Error: Problem login into Hippo: Login failed.

Copy link
Contributor

Choose a reason for hiding this comment

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

Oops, sorry, my misunderstanding - we should tweak this on the Hippo side. I like your solution though!

Copy link
Contributor

Choose a reason for hiding this comment

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

(that is to say.... we should do what you suggest even if it's only needed temporarily)

Cargo.toml Outdated
@@ -48,6 +49,7 @@ url = "2.2.2"
wasi-outbound-http = { path = "crates/outbound-http" }
wasmtime = "0.35.3"


Copy link
Contributor

Choose a reason for hiding this comment

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

Super pedantic: I don't think the extra line is needed?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

👌 Of course, I'll delete this blank line

Signed-off-by: lidongjies <lidongjies@gmail.com>
Copy link
Contributor

@itowlson itowlson left a comment

Choose a reason for hiding this comment

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

Looks good - thanks for your patience and your contribution!

@itowlson itowlson merged commit b54bb86 into fermyon:main Jul 25, 2022
@lidongjies lidongjies deleted the feature/plain-text-output branch July 25, 2022 20:14
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants