Bug with sending incorrect json doc - c++

I am testing example-crud for applying your framework in my project. But I noticed some bug.
I try to get value from the sent json into std::string with this way:
std::string test = userDto->userName->c_str();
ENDPOINT("POST", "users", createUser, BODY_DTO(Object<UserDto>, userDto))
{
std::string test = userDto->userName->c_str();
return createDtoResponse(Status::CODE_200, m_userService.createUser(userDto));
}
UserDto defined like this:
class UserDto : public oatpp::DTO {
DTO_INIT(UserDto, DTO)
DTO_FIELD(Int32, id);
DTO_FIELD(String, userName, "username");
};
If i send correct json with post query, i get value to "test" variable properly.
{
"id": 0,
"username": "test_user"
}
But if i change json`s field "username" to, as example, "Username" and send this json to endpoin, server will faild with error "Segmentation fault".
Server must'n faild under such condition. It must giv error message to the sender, and continue run.
How can i avoid the failure, if i just neen to get one simple value to variable?

Since the DTO field name and the JSON-key doesn't match, the userName of the received DTO is null. So the solution would be to add a nullptr check:
ENDPOINT("POST", "users", createUser,
BODY_DTO(Object<UserDto>, userDto))
{
OATPP_ASSERT_HTTP(userDto->userName, Status::CODE_400, "username is required!"); // check field for nullptr
std::string test = userDto->userName->std_str();
...
return createDtoResponse(Status::CODE_200, m_userService.createUser(userDto));
}
Source: https://github.com/oatpp/oatpp/issues/340#issuecomment-727563144

Related

Check for null values in request body using Wiremock

I am trying to setup a wiremock stub that will return a 400 error if any field has a null value in the json payload. Basically to simulate a Bad Request. I've been trying with a regex that matches any lowercase string for the json key but it doesn't seem to like it. I can't find any examples of what I want online so not sure if it's even possible.
My Bad Request body:
{
"cat": null,
"dog": {
"id": 1344
},
"horse": {
"id": 1
},
"fish": 1
}
My Stub:
wireMockServer.stubFor(post(urlEqualTo("/sample-api"))
.withRequestBody(matchingJsonPath("$.^[a-z]*", equalTo(null)))
.willReturn(aResponse()
.withStatus(400)
.withHeader("Content-Type", "application/json")))
In this example I would expect the stub to match "cat" as the value of it is null. This isn't the case. Can anyone tell me what I'm doing wrong?
In the WireMock documentation on Request Matching the section on JSON Path matching. In the source code there is a reference to com.jayway.jsonpath.JsonPath library used. The build.gradle refers to version 2.4.0. The documentation for the Jayway JSON Path library can be found on their Github project page. There is a good, but by no means perfect online evaluator here.
The WireMock documentation only shows support for Regular Expression for the node values in the form of the "matchesJsonPath". In the Jayway documenatation there is an online example: $..book[?(#.author =~ /.*REES/i)]. For this reason the only approach is to name all the nodes that are not allowed to be null.
In the below example mapping all the mentioned nodes will be tested, regardless of their depth (see #id). This mapping will not trigger if all the mentioned nodes are not null, but some unmentioned ones are.
{
"request": {
"urlPattern": "/sample-api",
"method": "GET",
"bodyPatterns" : [ {
"matchesJsonPath" : "$..[?(#.cat == null || #.dog == null || #.horse == null || #.fish == null || #.id == null)]"
} ]
},
"response": {
"status": "400",
"headers": {
"Content-Type": "application/json; charset=utf-8"
},
"jsonBody": {
"message": "some sapi message"
}
}
}
If you weren't aware of all possible keys, you could use a Custom Request Matcher to check if the request body contained any null values, and if so, return your 400 error. I'd recommend creating your own class, something that resembles...
public class BodyNullCheck extends RequestMatcherExtension {
#Override
public MatchResult match(Request request, Parameters parameters) {
JSONParser parser = new JSONParser();
try {
JSONObject body = (JSONObject) parser.parse(request.getBody().toString());
for(Iterator iterator = body.keySet().iterator(); iterator.hasNext();) {
String key = (String) iterator.next();
if (body.get(key) == null) {
return MatchResult.of(true);
}
}
} catch (ParseException ex) {
ex.printStackTrace();
}
return MatchResult.of(false);
}
}
The above takes the request body and converts it to a JSONObject, and then iterates over all keys in the JSONObject. If any of their values are null, then we will return true. If after iterating over all of them, a null value isn't found, we return false.

how to get data from {} in graphql

I want to get data about user addinfo(bool value).
when i do console.log(data.user), i can get data.user referred to below picture.
if when i do console.log(data.user.user), it shows that user is undefined referred to below picture.
{
user(token: "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJ1c2VybmFtZSI6ImI3ZTA5YmVhOTAzNzQ3ODQiLCJleHAiOjE1NjM4OTcxNzksIm9yaWdJYXQiOjE1NjM4OTY4Nzl9.QFB58dAvqIC9RBBohN1b3TdR542dBZEcXOG1MSTqAQQ") {
user {
id
addinfo
}
}
}
this code show that
{
"data": {
"user": {
"user": {
"id": "4",
"addinfo": false
}
}
}
}
I can't see the rest of your code, but if the code is fetching your users, there is a time before the request comes back where your user has not been fetched yet. It looks like your screenshot shows this. There is an undefined before the successful object.
You need to ensure that the data has come back first be checking if the data prop is truthy or some other way to check if the promise has completed yet.
ie
if (!data.user) return 'Loading...';
return (
<Switch>
...
In GraphQL I'm getting user info using e.g. below code:
async getUser(id) {
const result = await this.api.query({
query: gql(getUser),
variables: {
id,
},
});
return result.data.getUser || null;
}
I'm invoking it by:
const user = await userService.getUser(id);
and I do have access to user properties.
Maybe you're trying to get user data before they are retrieved and available?

How can I return JSON with HTTP code in Vibe.d?

I would like to return not only JSON, but also the HTTP response code.
I registering REST interface through URLRouter:
router.registerRestInterface(new ClientServerAPI);
Example of my REST implementation:
module clienserverapi.clientserver;
import api.clientserver;
import models.replies.client_versions;
/**
Implementation of Client-Server API.
*/
class ClientServerAPI : IClientServerAPI {
#safe:
ClientVersions getSupportedClientVersions() {
bool[string] unstableFeatures;
return ClientVersions(supportedVersions.dup, unstableFeatures);
}
}
In the REST interface generator the response codes are handled automatically and as you can't pass in a HTTPServerResponse/HTTPServerRequest argument into your REST methods, you can't control what status gets returned.
However there are some built-in statuses which get handled:
200/204 are returned based on content
400 Bad request for mismatched arguments
404 Not found for unmatched routes
500 internal server error is returned on most exceptions
(outside of debug mode) unauthorized / bad request / forbidden are sent
See also: REST interface documentation
and you can control any status code using HTTPStatusException, however it is treated as error and will result in a predefined error json which has statusMessage as exception message set and returns the HTTP status code you pass to it. (this is probably what you want for error handling)
You can also change what the errors look like by setting the errorHandler to a RestErrorHandler delegate in your RestInterfaceSettings.
Alternatively, depending on what you want to do, you can use a WebInterface which is a lot like a rest interface, but doesn't have some convenience functions REST interfaces do, but instead can fully access the request/response arguments and can basically do anything like a normal http route and has some other convenience functions you can use.
In theory you could abuse the errorHandler + HTTPStatusException with valid HTTP status codes if you want to return custom success codes with your data, but I would discourage that and instead go with web interfaces if that's what you are after.
However if all you want to do is having custom error codes with a custom, but consistent, error page then I would definitely go with REST interface with an errorHandler.
Your could could now look like this:
import vibe.vibe;
import std.uni;
#safe:
void main() {
auto server = new HTTPServerSettings;
server.port = 3000;
server.bindAddresses = ["::1", "127.0.0.1"];
auto router = new URLRouter;
RestInterfaceSettings settings = new RestInterfaceSettings();
// this is how the error page will look on any thrown exception (like HTTPStatusException)
settings.errorHandler = (HTTPServerRequest req, HTTPServerResponse res,
RestErrorInformation error) #safe {
res.writeJsonBody([
// design this however you like
"ok": Json(false),
"error": serializeToJson([
"status": Json(cast(int)error.statusCode),
"message": Json(error.exception.msg),
"parent": Json("/api/something")
])
]);
};
router.registerRestInterface(new Impl, settings);
listenHTTP(server, router);
runApplication();
}
interface RestAPI {
string getGreeting(string name);
}
class Impl : RestAPI {
string getGreeting(string name)
{
// throw an HTTP Bad Request error when name is empty
if (name.length == 0)
throw new HTTPStatusException(HTTPStatus.badRequest, "Name parameter cannot be empty!");
// throw an HTTP Conflict error code when name is Bob
if (sicmp(name, "bob") == 0)
throw new HTTPStatusException(HTTPStatus.conflict, "Server cannot greet Bob!");
return "Hello, " ~ name ~ "!";
}
}
and your server will then respond something like:
{
"ok": false,
"error": {
"message": "Server cannot greet Bob!",
"status": 409,
"parent": "/api/something"
}
}
You can try hunt framework, sample code for Rest api:
module app.controller.myapi;
import hunt.framework;
import app.message.UserMessage;
class MyapiController : Controller
{
mixin MakeController;
#Action
JsonResponse test()
{
UserMessage user;
user.id = 1;
user.name = "MyName";
user.email = "test#domain.com";
return new JsonResponse(user);
}
}
Your response struct:
module app.message.ResultMessage;
struct UserMessage
{
int id;
string name;
string email;
}
Response result is:
[ "id": 1, "name": "MyName", "email": "test#domain.com" ]

Facebook API, Unity3D. Can't get user's email

I am trying to get user's email using FB.API() method, all code is below
public class FacebookCase : MonoBehaviour {
// Use this for initialization
void Start () {
FB.Init(new Facebook.InitDelegate(initComplete), null, null);
}
private void initComplete()
{
FB.Login("email,publish_actions", new Facebook.FacebookDelegate(loginComplete));
}
private void loginComplete(FBResult result)
{
FB.API("/me?fields=first_name,last_name,email", Facebook.HttpMethod.GET, graphCallback);
}
private void graphCallback(FBResult result)
{
Debug.Log(result.Text);
}
}
That code gives me first and last name, but instead of email address I've got 'id=2385905023865'.
Why it so? How to get email?
The id field is always returned. It's not shown "instead" of the email field. My suspicion is that you didn't request the email permission properly during login. Please check accordingly...

How to route after calling commit()

I am struggling a little with what to do after I call commit(). I want to determine how to route the user, depending on commit() being successful or if the server returns an error.
I read somewhere that if there is an error on the server then it can return a status code of >400 and errors as follows:
{ 'errors' : [ { 'errorCode' : [ 'duplicate-user' ] } ] }
On the client-side I have the following:
App.UsersController = Ember.ObjectController.extend({
createUser : function () {
'use strict';
var user = App.User.createRecord({
firstName : $("#firstName").val(),
lastName : $("#lastName").val(),
primaryEmailAddress : $("#primaryEmailAddress").val(),
password : $("#password").val()
}),
commitObserver = Ember.Object.extend({
removeObservers : function (sender) {
sender.removeObserver('isError', this, 'error');
sender.removeObserver('isValid', this, 'success');
},
error : function (sender, key, value) {
this.removeObservers(sender);
App.Router.router.transitionTo('duplicateuser');
},
success : function (sender, key, value) {
this.removeObservers(sender);
App.Router.router.transitionTo('usercreated');
}
});
user.get('transaction').commit();
user.addObserver('isError', commitObserver.create(), 'error');
user.addObserver('isValid', commitObserver.create(), 'success');
}
});
(Note: I am not using 'Ember.TextField' in my HTML hence the use of jQuery)
I have a few questions:
Is this the correct/best approach for handling commit()?
I've found I have to remove both observers as isValid is called after isError - is this to be expected?
How/can I access the server response as I want to be able to make a routing decision based on the error code?
The only way I can reference the router is through App.Router.router - is there a cleaner way?
If there is an error, do I need to do anything to remove the record from the store so it doesn't re-committed in the future?
From within a controller, you can do this:
this.get('target').transitionTo('another.route')
or, you can send an event to the current route and transition from there:
this.get('target').send('eventName');
or if you need to pass a model:
this.get('target').send('eventName', this.get('content'));
Simply use controller.transitionToRoute("your.route");
See this link for the source code...