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

How to check for specific types of errors? #292

Open
flyte opened this issue Dec 15, 2021 · 8 comments
Open

How to check for specific types of errors? #292

flyte opened this issue Dec 15, 2021 · 8 comments

Comments

@flyte
Copy link

flyte commented Dec 15, 2021

I want to look up a bucket by name and create it if it doesn't exist. Something like the following pseudocode:

bucket, err := client.BucketsAPI().FindBucketByName(ctx, "mybucket")
if err != nil {
    // How can I check if the bucket was not found, vs any other error?
    if <error is a not-found error> {
        createBucket(ctx, "mybucket")
    } else {
        return fmt.Errorf("error looking up InfluxDB2 bucket: %v", err)
    }
}
@vlastahajek
Copy link
Contributor

@flyte, there is no specific error in the client API.
Returning error in case of no item is found is the default behavior for server REST API.

@flyte
Copy link
Author

flyte commented Dec 20, 2021

How should I check for a 404 error from the server then?

@lesam
Copy link
Contributor

lesam commented Dec 20, 2021

@rogpeppe FYI for issues with the go client

@vlastahajek
Copy link
Contributor

How should I check for a 404 error from the server then?

@flyte , when server sesponds with an error, in most cases, the returned error by client API is http.Error, where you can check status code.
However, in the case of FindBucketByName, as a server responds with empty result if name is not found, this method creates new generic error for the API consistency.

@flyte
Copy link
Author

flyte commented Dec 21, 2021

Sorry, I still don't understand. I appreciate your responses but you're really going to have to spell it out for me I'm afraid.

I recognise that a generic error is returned in this case, so does that mean I can't assert that the bucket was not found as opposed to a connection error, for example?

@vlastahajek
Copy link
Contributor

All that means, there is no nice solution for your use-case, unfortunately. We will analyze if there should be some improvement in the API for such cases.
So, for now, I would recommend trying to create a bucket in case of an error. In the worst case, you will end up with two connection errors.

@pabigot
Copy link
Contributor

pabigot commented Dec 22, 2021

How should I check for a 404 error from the server then?

when server sesponds with an error, in most cases, the returned error by client API is http.Error, where you can check status code.

The functions in WriteAPIBlocking also appear to be exceptions; see #293.

@pabigot
Copy link
Contributor

pabigot commented Dec 22, 2021

For the non-blocking API I've found at least some errors are not http.Error, but rather one of those wrapped by fmt.Errorf(). You can use err.Unwrap and type assertions, but to handle cases where the error may sometimes not be wrapped by fmt.Errorf() this idiom seems more robust:

var nerr net.Error
var herr *http2.Error
var merr *protocol.MetricError
if errors.As(err, &nerr) {
  log.Printf("EC: net.Error (perm=%t): %s", !nerr.Temporary(), nerr.Error())
} else if errors.As(err, &herr) {
  switch herr.StatusCode {
  case 401: // handle unauthorized
    fallthrough
  case 404: // handle not found
    fallthrough
  default:
    log.Printf("EC: http2.Error: %d: %s\n", herr.StatusCode, herr.Error())
  }
} else if errors.As(err, &merr) {
  if errors.Is(merr, protocol.ErrInvalidName) {
    log.Printf("EC: measurement name missing")
  } else {
    log.Printf("EC: MetricError: %s", merr.Error())
  }
} else {
  log.Printf("EC: Unhandled %T: %s", err, err.Error())
}

protocol.MetricError handles some errors detected before any network connection is made.

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

No branches or pull requests

4 participants