There are three categories of exceptions that may be thrown:

These are known exceptions, either an exception that occurred in the request pipeline (such as max retries or timeout reached, bad authentication, etc.) or Elasticsearch itself returned an error (could not parse the request, bad query, missing field, etc.). If it is an Elasticsearch error, the ServerError property on the response will contain the the actual error that was returned. The inner exception will always contain the root causing exception.
These are unknown exceptions, for instance a response from Elasticsearch not properly deserialized. These are sometimes bugs and should be reported. This exception also inherits from ElasticsearchClientException so an additional catch block isn’t necessary, but can be helpful in distinguishing between the two.
Development time exceptions
These are CLR exceptions like ArgumentException, ArgumentOutOfRangeException, etc. that are thrown when an API in the client is misused. The .ThrowExceptions() setting has no bearing on these as they will always be thrown, and also should not be handled by a consumer.