How to serve a 500 page using Sinatra? - sinatra

Since Sintra is a Rack app, I think it could use Rack way:
get '/' do
result = true
if result
['200', {'Content-Type' => 'application/json'}, [{result:true}.to_ json]]
else
binding.pry
['500', {'Content-Type' => 'application/json'}, [{result:false}.to _json]]
end
end
It doesn't work, it alway return a 500 page, whether the variable is true or false

If you actually have this literal code in your app:
{result:true}.to_ json # <<< whitespace that shouldn't be there
Then your code will have a runtime exception (probably missing method to_ or unknown variable or method json), and that's why you get a 500 error every time.

You can return a Rack-like array as a response like this, but the first item of the array needs to be a Fixnumspecifically, rather than just something that will result in a number when parsed with to_i. Sinatra checks the type of the entry to determine how to handle the response.
Your response would be valid in a “pure” Rack app, but not in Sinatra. Arguably this is a bug in Sinatra, or at least the docs which says any valid Rack response is valid.
Sinatra tries to return the whole array as the body of the reponse (since it reponds to each), but then fails when trying to process the array since the contents aren’t all Strings.
To fix it simply change the status codes in your responses from Strings to Fixnums:
[200, {'Content-Type' => 'application/json'}, [{result:true}.to_json]]

Related

regex check and proceed next call

Iam new to gatling and scala.
I was trying to validate regex in galting-scala.
My scenario.
from the response capture (regex) X values, If available then execute step-ABC
If X value of component not found, ignore step_ABC
Your example uses .exists, which asserts that the regex must be matched and returns a boolean, not the value of the match. So the "logoId" session variable will always get set, but won't have any data useful for making a subsequent request. Additionally, since the logo is optional in your case, you don't want the scenario failing if it isn't there.
Optional checks and the gatling EL support your use-case.
.exec(
http("get merchant")
.get("some url")
.check(
regex(""""logoId":(.+?),""").optional.saveAs("logoId")
)
.doIf("${logoId.exists()}") {
exec(...)
}

How to change Mojolicious Lite default error not found to a custom json response

I'm creating a json web service using Mojolicious Lite.
By default Mojolicious returns a HTML response for a server error or not found error.
Is there a way to overwrite this to a custom JSON response?
Here are two approaches:
Use json as the app's default format and use a not_found.*.json.ep template
use Mojolicious::Lite;
app->renderer->default_format('json');
app->start;
__DATA__
## not_found.development.json.ep
{"not":"found","code":404,"data":{"key1":"value1","key2":[42,19,"value3"]}}
Override json payload with a before_render hook.
use Mojolicious::Lite;
hook before_render => sub {
my ($c,$args) = #_;
if ($args->{template} && $args->{template} eq 'not_found') {
$args->{json} = { "too bad" => "so sad" };
}
};
app->start;
It's been a minute, but in Mojo 9 in a full app I've just been returning JSON and returning the status:
$c->render( json => $json, status => 404 );
But, I also have a catch-all route at the end of my setup:
$self->routes->any('/*')->to( ... );
Note, however, that there are some decisions to make about HTTP codes and application-level messaging. For example, accessing a defined and valid endpoint that returns zero search results could easily return 200 and an empty JSON array. The endpoint was there, the server knew how to handle it, and zero list items can be seen as valid as any other number. See I've been abusing HTTP Status Codes in my APIs for years, for example.
The Rendering guide discusses how to customize these responses.

PATCH / Post with curl in Classic ASP

I was thrown into a pretty old project, which is made in classic ASP. For our needs, I need to make a simple curl-request, to update some data.
I'm pretty new to ASP, so I looked for similar problems. I stumbled upon this
question here:
How can I post data using cURL in asp classic?
I tried to adapt as much as possible, but it seems like I'm missing an important thing and here I need your help:
functions.asp
public function makeCurlRequest(strMethod)
Dim http: Set http = Server.CreateObject("WinHttp.WinHttpRequest.5.1")
Dim privateKey
privateKey = "abc def"
Dim url: url = "https://sandbox.uberall.com/api/locations/322427?private_key=" & privateKey
Dim data: data = "{""location"":{""openingHours"":[{""dayOfWeek"":1,""from1"":""07:01"",""to1"":""07:02""}]}}"
'method needs to be PATCH
With http
Call .Open(strMethod, url, False)
Call .SetRequestHeader("Content-Type", "application/json")
Call .Send(data)
End With
If Left(http.Status, 1) = 2 Then
response.write("updated")
response.end()
Else
'Output error
Call Response.Write("Server returned: " & http.Status & " " & http.StatusText)
End If
end function
In my file, I simply call makeCurlRequest("PATCH").
Now it does indeed print "updated", so I guess I'm retrieving a 200, but the fields aren't updated.
Regarding to the uberall API, they require a location-object, which should be this, what is currently in my data-variable. (Checked it via a JSON-validator).
For a better readability, I'll provide the indented code as well, maybe here is an error:
{
"location":{
"openingHours":[
{
"dayOfWeek":1,
"from1":"07:01",
"to1":"07:02"
}
]
}
}
The ID's are correct, I double-checked that already. Maybe the payload is wrong? What might be the problem? Maybe data needs to be provided otherwise instead of this approach?
Looking at the examples on Uberall Tutorials Page
It looks as though the encapsulation of the location object is not necessary, instead structure the body like
{
"openingHours":[
{
"dayOfWeek":1,
"from1":"07:01",
"to1":"07:02"
}
]
}
In the code, change the data variable to be;
Dim data: data = "{""openingHours"":[{""dayOfWeek"":1,""from1"":""07:01"",""to1"":""07:02""}]}"
Must admit I had to dig around in the documentation to find an example that showed how they expected the body of the request to be structured, which isn't great for an API. Also if the payload was wrong you should be getting back an error so you know there was a problem with the payload, something along the lines of HTTP 400 Bad Request would make sense.
It's also possibly that the API uses HTTP 200 OK for everything, in which case any errors might get missed, so while testing you could just do something like this;
Dim http: Set http = Server.CreateObject("WinHttp.WinHttpRequest.5.1")
Dim privateKey
privateKey = "abc def"
Dim url: url = "https://sandbox.uberall.com/api/locations/322427?private_key=" & privateKey
'Purposefully passing the wrong structure to see what is returned.
Dim data: data = "{""location"":{""openingHours"":[{""dayOfWeek"":1,""from1"":""07:01"",""to1"":""07:02""}]}}"
'method needs to be PATCH
With http
Call .Open(strMethod, url, False)
Call .SetRequestHeader("Content-Type", "application/json")
Call .Send(data)
End With
'Not bothered about the status for now, just give me the response.
Call Response.Write("Server returned: " & http.Status & " " & http.StatusText)
Call Response.Write("Body: " & http.ResponseText)

Route passing in Sinatra for single page app with REST resources

I'm trying to make a single page website with sinatra in the backend. I want all GET-requests with preferred accept-header "text/html" to return the same page, BUT all requests that wants json to get json-data.
Example:
A GET call to '/users' with accept set to 'text/html' should return index.html.
A GET call to '/users' with accept set to 'application/json' should return the JSON-data with users.
I have tried using a catch-all method for html and using accept-checks like this:
# Generic html giver for angular routing
get //, :provides => 'html' do
pass unless request.preferred_type.to_str == 'text/html'
erb :index
end
# Give users as JSON
get '/users', :provides => 'json' do
pass unless request.preferred_type.to_str == 'application/json'
'["dummy", "array"]'
end
...but it doesn't seem to pass to the second route when preferred_type isn't text/html.
Note: I'm useing the string check on preferred_type, since using request.accept? catches all with browsers giving "*/*" as last accept header.
Oh, it seems like the culprit is:
:provides => 'json'
Without it, the passing works as expected. I guess it's a bug then.

HTTP reponse for error in REST call for Mojolicious

The mojolicious application that I use is JSON based, that is the interaction between the client and the server is more of an exchange of JSON structured data.
I am trying to implement a standard way of handling errors with proper HTTP response code when an error occurs during one of the REST calls. What is the best way of implementing such a standard and where do I do it?
I see a couple of ways of doing it
Create a class and list all the error response and its associated content, a call could be made to this class with the response code, which would return the JSON structure(combination of hashes and arrays) containing all the associated entry, then use the render_json() method in controller and return this as a response to the client
I can create a table in the Database with entry for all the fields that are required for the response, use the filed to access the JSONstructure, create the appropriate response and use render_json() in controller and return this as a response to the client.
Example of error response might be like
{
"Message": "The requested resource is not found"
"Type" : "http://this.is.an.error.com/error/resource_not_found",
"ErrorCode" : 404,
"Created" : "2012-11-05T11:59:29-05:00",
"Request" : "GET /types/Foo/instances"
}
What is the right way of standardizing such a response?
As titanofold mentioned, I'd go for option 2.
Regarding error codes, try to stick with standard HTTP Response Status Codes.
Besides setting the ErrorCode property in your JSON, you should send the status code in the response header because:
you can treat errors in a single place - the error callback of your javascript function
in the future you might have other consumers of your backend (mobile apps for example)
this is why they have been invented
You can achieve that extremely simple with Mojolicious:
$self->render_json( {
Message => "The requested resource is not found",
Type => "http://this.is.an.error.com/error/resource_not_found",
ErrorCode => 404,
Created => "2012-11-05T11:59:29-05:00",
Request => "GET /types/Foo/instances",
},
status => 404);
The wonderful things about standards are that there are so many to choose from, and if you don't like any of them you can make your own.
As to the REST structure, that's up to you. I would go for the generic 'code' rather than 'ErrorCode' as you should return a code on success, too.
For your method options, I'd go with option 2.
I would also opt for option 2. But I do not understand the need for the error details to be part of the database. I would rather suggest you use a the OO concept of base class holding all the error details and the inheriting it to other classes, making sure you have access to it.