In Locust I need to get original timeout or connection error when using catch_response=True to validate response - locust

There is a good explanation how to validate response of the request
https://docs.locust.io/en/stable/writing-a-locustfile.html#validating-responses
However there are cases when status_code=0 (case of connection error or timeout).
I would like to be able to pass original error when it happens in response.failure().
For example:
with self.client.get("/some_test_url/", catch_response=True) as response:
if response.status_code == 200 and _some_other_errors_checks_:
response.failure("Response is 200 but contain _some_error_")
if response.status_code == 0: # This is case of timeout or connection error
response.failure(????????)

You could see the original error using response.error property.
If something happened and the response is an error response or contains an error you could raise the original error using response.raise_for_status() that will throw the original error of the response if exists

Related

Adding information to Golang Gin HTTP error responses

I am trying to return a custom error response when an HTTP 500 Internal Error is encountered. If I use c.JSON(http.StatusInternalServerError, CustomError{}) when a database write error occurs, Gin ignores my CustomError struct and substitutes a default "500 server Error" message.
How can I add information to the default response or return a custom response while still using the HTTP 500 Internal Server error code?
This is what I am trying to accomplish. Notifying users of a duplicate entry in the Mongo database. Gin ignores my DBErrorResponse struct and just returns the default 500 error json response.
_, err := handler.collection.InsertOne(handler.ctx, data)
if err != nil {
if mongo.IsDuplicateKeyError(err) {
dbErr := err.(mongo.WriteException)
c.JSON(
http.StatusInternalServerError,
models.DBErrorResponse{
Type: "Write Exception",
Code: dbErr.WriteErrors[0].Code,
Err: "similar record exists",
})
return
}
If the error is caused by a user providing a duplicate key, it's not an internal server error. You might want to use something like BadRequest(400), which suits duplicate value far more, if provided by the client. Thus, you should be able to return a custom error message with StatusCode 400.
Additionally, as far as I know, InternalServerError(500) is not designed to provide a 'server-side' problem feedback to the client, since, well, it's not public information. Although I'm not certainly sure if that's so and if is, why.
UPD: As Gavin mentioned, httpCode 409 is far better choice, here is the doc:
HTTP 409 error status: The HTTP 409 status code (Conflict) indicates that the request could not be processed because of conflict in the request, such as the requested resource is not in the expected state, or the result of processing the request would create a conflict within the resource.

HTTP Sender and REST conventions

I'm writing a C# Web API server application, and will send JSON to it via a Mirth HTTP Sender destination. This post is about how to handle error conditions. Specifically, there are three scenarios I want to handle:
Sometimes we take the C# application server offline for a short period for system upgrade or maintenance, and Mirth is unable to connect at all. I want Mirth to queue all messages in order, and when the server is available, process them in the order they were received.
The server receives the request, but rejects it due to a problem with the content of the request, e.g., missing a required field. In accordance with REST conventions, the server will return a 400-level HTTP response. This message would be rejected every time it's submitted, so it should not be re-sent; just log the failure and move on to the next message.
The server receives the request, but something goes wrong on the server, and the server returns an HTTP 500 Server Error response. This would be the appropriate response, for example, when something in the server environment has gone wrong. One real-world example was the time the Web API server was running, but somebody rebooted the database server. REST conventions would suggest we continue to resend the message until the transient problem has been resolved.
For #1, initially I had it queue on failure/always, but it appears the response transformer never runs for messages that were queued (at least, the debug statements never showed in the log). I have turned queueing off, and set it to retry every ten seconds for an hour, and that seems to give the desired behavior. Am I on the right track here, or missing something?
For #2 and #3, returning any HTTP 400 or 500 error invokes the 1-hour retries. What I want is to apply the 1-hour retries for the 500 errors, but not the 400 errors. I’ve tried responseStatus = SENT in the response transformer, but the response transformer only runs once, after the hour has expired, and not for each retry.
This seems like a common problem, yet I’m not finding a solution. How are the rest of you handling this?
You're close!
So by default, the response transformer will only run if there's a response payload to transform. For connection problems, or possibly for 4xx/5xx responses that contain no payload, the response transformer won't execute.
However, if you set your response data types (From the Summary -> Set Data Types dialog, or from the Destinations -> Edit Response, Message Templates tab) to Raw, then the response transformer will execute all the time. The reason being that the Raw data type considers even an empty payload to be "transformable".
So turn queuing back on, and set your response data types to Raw. Then in the response transformer, if you look at the Reference tab there's a category for HTTP Sender:
You'll want the "response status line", that's the "HTTP/1.1 200 OK" line of the response that contains the response code. Here's a response transformer script that forces 4xx responses to error:
if (responseStatus == QUEUED) {
var statusLine = $('responseStatusLine');
if (statusLine) {
var parts = statusLine.split(' ');
if (parts.length >= 2) {
var responseCode = parseInt(parts[1], 10);
// Force 4xx responses to error
if (responseCode >= 400 && responseCode < 500) {
responseStatus = ERROR;
responseStatusMessage = statusLine;
}
}
}
}

[Swift, Alamofire]: responseValidationFailed with error code 400

My problem is basically in the title. The code that I am trying to run is just below. VVV
let unfollow = "https://api.instagram.com/v1/users/\(userID)/relationship?access_token=\(access_token)&action=unfollow"
Alamofire.request(unfollow, method: .post).validate().responseJSON(completionHandler: {
response in
switch response.result {
case .success(let value):
let data = JSON(value)["data"]
print(data["outgoing_status"].stringValue)
case .failure(let error):
print(error)
}
})
The exact console error I recieve is: responseValidationFailed(Alamofire.AFError.ResponseValidationFailureReason.unacceptableStatusCode(400))
I am using the Instagram API by the way but I don't think that that is necessarily related to the issue.
Any help greatly appreciated.
The erro log responseValidationFailed(Alamofire.AFError.ResponseValidationFailureReason.unacceptableStatusCode(400)) clearly shows that you are getting 400 error. Which is explained in W3.org as
400 Bad Request:
The request could not be understood by the server due to malformed syntax. The client SHOULD NOT repeat the request without modifications.
So you need to chek you request URL if it is correct.
Also, you are using validate() method of request which is supposed to get response status codes 200...299, but you are getting 400 as response code. Thats why it is mentioned as unacceptableStatusCode(400) in error log.
Seel this also.

What response code should we use on a REST reply when the response data is an error message

We have a REST service where the response to a request may be an error message. A simple example is the request is a formula to calculate and the formula might have a divide by zero. In that case the response is an error code and error message.
So the communication with the REST service is all good. The service itself is responding to the request. But the response is an error message instead of the expected result.
In this case what is the best response code to use? 200 to say the entire communication process is good and we look in the returned JSON to determine if it’s an error? 500 to say it’s an error, but then look to see if we have the expected JSON to determine it was an error in the calculation? Some other code which says we are getting a response from the server but the response is an error message?
A simple example is the request is a formula to calculate and the formula might have a divide by zero. [...] In this case what is the best response code to use?
I would use 422 Unprocessable Entity
The 422 (Unprocessable Entity) status code means the server understands the content type of the request entity (hence a 415(Unsupported Media Type) status code is inappropriate), and the syntax of the request entity is correct (thus a 400 (Bad Request) status code is inappropriate) but was unable to process the contained instructions. For example, this error condition may occur if an XML request body contains well-formed (i.e., syntactically correct), but semantically erroneous, XML instructions.
Don't rely only on HTTP code anyway, always add a description of the error in the body. I believe it's common practice to have all your endpoints reply with a JSON with success (true or false) and something like error (with the error message) if success if false, or data (with the result) if success is true.
For error messages we can use 4XX Bad Request
Look at this post, for various status codes.
http://www.restapitutorial.com/httpstatuscodes.html

Jmeter : How to check for empty text response

I am writing a jmeter framework to validate Rest web services.I have a csv file having the list of URLS , Response code and response messages Eg :
/api/input/checkUploadRequirement application/x-www-form-urlencoded 200 NOTREQUIRED
likewise I have many URL's.Few of the URL's does not return anything and for them I have empty cell\field in the csv file Eg:
/api/input/savedetail sessionTrackingID=58ec9684-dfd-4c8f4796-f897 application/x-www-form-urlencoded 200 .
Now If I validate the empty Text response in Jmeter for above URL, I am getting "Assertion failure message: Response was null"
Please help me to validate empty text response from http request
You can use Size Assertion and test for size of response:
http://jmeter.apache.org/usermanual/component_reference.html#Size_Assertion
You can do it via Beanshell Assertion. If null response is something you expect, substitute Response Assertion with Beanshell Assertion. Use the following code in "Script" area:
if (ResponseData.length != 0) {
Failure = true;
FailureMessage = "Expected empty response, got: " + new String(ResponseData);
}
This code will mark parent sampler as passed if response is empty and fail it if even a single character will be returned.
See How to Use JMeter Assertions in Three Easy Steps guide for advanced information on conditionally setting pass/fail criteria in your JMeter test