how to return a validation property on a hapi reply like the way Joi library does it - hapi.js

I have my own custom validation on a property and I'd like to return a 400 response that is similar to the the JOI.validation that is returned on the other fields. This means that in addition to the error and message I'd like to return a validation property as well - so that the client can know which field to highlight.
So, instead of this
{
"statusCode": 400,
"error": "Bad Request",
"message": "phone validation error: invalid phone number"
}
I'd like to reply with this
{
"statusCode": 400,
"error": "Bad Request",
"message": "phone validation error: invalid phone number"
"validation": {
"source": "payload",
"keys": [
"phone"
]
}
How do I add the validation the the hapi reply?
I've been doing this - which has not been working
e.validation =
{
source: "payload",
keys: [
"phone"
]
}
reply(Boom.badRequest(e));
I'm also assuming that I cannot have custom validators for Joi, otherwise I would have just extended Joi. But, is there a Joi validation error type or object I can use in the reply to get Joi like object structure in my response.
BTW, my phone validation is not a simple regex and has special cases so I cannot use the Joi built in regex validator.

If you inspect the object returned by boom.badRequest('some message'), you'll get:
{ data: null,
isBoom: true,
isServer: false,
output:
{ statusCode: 400,
payload:
{ statusCode: 400,
error: 'Bad Request',
message: 'some message' },
headers: {} },
reformat: [Function] }
So you actually need to do something like
var errObj = Boom.badRequest(e);
errObj.output.payload.validation =
{
source: "payload",
keys: [
"phone"
]
}
reply(errObj);

Try this:
var errObj = Boom.badRequest(e);
errObj.validation =
{
source: "payload",
keys: [
"phone"
]
}
reply(errObj);

Related

Why doesn't GraphQL.NET honour the errors.extensions schema?

I recently rewrote some GraphQL services from Java to .NET Core.
In Java, I was able to provide custom error messages to the clients using the errors.extensions in the response, ie:
{
"data": {
"someMutation": null
},
"errors": [{
"cause": null,
"message": "Unauthorized",
"httpStatusCode": 0,
"extensions": {
"uiMessage": "Oh no, your session expired. You'll need to login again to continue.",
"httpStatusDescription": "Unauthorized",
"httpStatusCode": 401
},
"errorType": "ValidationError",
"path": null,
"localizedMessage": "Unauthorized",
"suppressed": []
}
]
}
However, in .NET, I don't seem to be able to replicate this format.
ErrorInfo.Extensions is added to the root of the response, not to the the Errors object itself, eg:
{
"data": {
"someMutation": null
},
"errors": [{
"message": "Auth token not provided"
}
],
"extensions": {
"httpStatusCode": 401,
"httpStatusDescription": null,
"uiMessage": "Oh no, your session expired. You'll need to login again to continue.",
}
}
The GraphQL spec reads (ref https://spec.graphql.org/October2021/#sec-Errors, https://spec.graphql.org/October2021/#example-8b658):
GraphQL services may provide an additional entry to errors with key
extensions. This entry, if set, must have a map as its value. This
entry is reserved for implementors to add additional information to
errors however they see fit, and there are no additional restrictions
on its contents.
eg:
{
"errors": [
{
"message": "Name for character with ID 1002 could not be fetched.",
"locations": [{ "line": 6, "column": 7 }],
"path": ["hero", "heroFriends", 1, "name"],
"extensions": {
"code": "CAN_NOT_FETCH_BY_ID",
"timestamp": "Fri Feb 9 14:33:09 UTC 2018"
}
}
]
}
I created a new test project (.NET Core 3.1) using the latest versions of the libraries (GraphQL 7.1.1 et al) but am still unable to add custom properties to errors.extensions.
This is the test mutation which intentionally throws an exception:
Field<StringGraphType>("greet")
.Argument<NonNullGraphType<StringGraphType>>("name")
.Resolve(context => {
try {
throw new Exception("Invalid input");
return "Hello " + context.GetArgument<String>("name");
} catch(Exception ex) {
// This doesn't seem to get returned anywhere in the response
Dictionary<String, object> extraData = new Dictionary<string, object>();
extraData.Add("error1", "message1");
// Add the error to the response using the overloaded constructor
context.Errors.Add(new ExecutionError("Oh dear, that went wrong", extraData));
// This gets added to the root of the response
context.OutputExtensions.Add("error2", "message2");
return null;
}
});
the mutation to invoke it:
mutation {greet(name:"Chewbacca")}
and the response (I don't know where errors.extensions.details comes from):
{
"errors": [
{
"message": "Oh dear, that went wrong",
"extensions": {
"details": "GraphQL.ExecutionError: Oh dear, that went wrong"
}
}
],
"data": {
"greet": null
},
"extensions": {
"error2": "message2"
}
}
I would imagine that the GraphQL.NET library would expose an Extensions dictionary on the ExecutionError object so one could add custom values in the usual manner, eg:
ExecutionError executionError = new ExecutionError("Oh dear, that went horribly wrong");
executionError.Extensions.Add("customError", "Your custom error here")
context.Errors.Add(executionError);
Which would result in a response similar to this:
{
"data": {
"someMutation": null
},
"errors": [{
"message": "Oh dear, that went horribly wrong",
"extensions": {
"customError": "Your custom error here"
}
}
]
}
I am hopeful that some bright individual in the community can (slap me upside the head and) point me in the right direction.

Loopback 4 auto generated model with required id failing validation

I'm using an automated script that runs an auto-generation model using lb4 cli.
Looks like validation expects id to be provided, but swagger missing it in its schema. Why I can't see the id property in swagger?
PLEASE NOTE! I don't want to modify manually my models
lb4 model activity --dataSource DS --table activity
Created model:
export class Activity extends Entity {
#property({
type: 'string',
required: true,
id: 1,
postgresql: {
columnName: 'id',
dataType: 'uuid',
dataLength: null,
dataPrecision: null,
dataScale: null,
nullable: 'NO',
},
})
id: string;
...
}
When I run the swagger tool and try to POST new activity, it missing the id field and returns the following error:
{
"error": {
"statusCode": 422,
"name": "ValidationError",
"message": "The `Activity` instance is not valid. Details: `id` can't be blank (value: undefined).",
"details": {
"context": "Activity",
"codes": {
"id": [
"presence"
]
},
"messages": {
"id": [
"can't be blank"
]
}
}
}
}
If I add a property id manually, then it throws a validation error:
{
"error": {
"statusCode": 422,
"name": "UnprocessableEntityError",
"message": "The request body is invalid. See error object `details` property for more info.",
"code": "VALIDATION_FAILED",
"details": [
{
"path": "",
"code": "additionalProperties",
"message": "must NOT have additional properties",
"info": {
"additionalProperty": "id"
}
}
]
}
}
Change your #model() by #model({settings: {strict: false}}) and add this line [prop: string]: any; into your model
#model({settings: {strict: false}})
[prop: string]: any;

How to check unwanted parameters in response body in Postman?

Refer to the below response body as an example, the only valid parameters of the response body are StatusCode and Message. We can add assertions and easily check if the fields are present with the correct value or not.
Now, I want to check if any unwanted parameters are being populated in the response and make the correction in this case. Is there any way to check this in postman using test assertions?
{
"statusCode": 200,
"message": "Here is the detail message",
"data": "Unwanted parameter"
"UnwantedLink": "www.unwantedlink.com"
}
You can check keys using chaijs
const res = pm.response.json();
pm.test("check keys in response", () => {
pm.expect(res).have.all.keys("statusCode", "message");
})
Example 2 cases below
use json schema validation :
you can use https://www.jsonschema.net/home to generate schema , click setting and settings and set options like:
schema = {
"type": "object",
"properties": {
"statusCode": { "type": "integer" },
"message": { "type": "string" }
},
"additionalProperties": false
};
pm.response.to.have.jsonSchema(schema)

Customizing Laravel validation JSON message format - Laravel

I'm trying to figure out how to customize the Form requests to validate
By default Laravel gives a good enough JSON format for validation errors but what if we want to customize it?
{
"message": "The given data was invalid.",
"errors": {
"email": [
"Please enter email address."
],
"password": [
"Please enter password."
]
}
}
for a particular project, we decided to change the format to this.
{
"success": false,
"errors": [
{
"email": "Please enter an email address."
},
{
"password": "Please enter a password."
}
]
}
Any help would be great.
Regards.
Please try the following.
public function render($request, Throwable $e)
{
if ($e instanceof ValidationException) {
// Custom response
$response = [
'success' => false,
'error' => $e->errors()
];
return response()->json($response, 422);
}
return parent::render($request, $e);
}

Error JSONP Store

I am retrieving information for a List via JSONP and am getting the following error in console browser: "unexpected token : "
My store:
Ext.define ('Projeto.store.Mural', {
extend 'Ext.data.Store'
requires: [
'Projeto.model.Mural'
]
config: {
autoLoad: true,
model: 'Projeto.model.Mural'
storeId 'MuralStore'
Proxy {
type: 'jsonp'
url: 'http://URL/mural'
reader: {
type: 'json',
rootProperty: 'rows'
}
}
}
});
My List:
Ext.define ('Projeto.view.MuralList', {
extend 'Ext.dataview.List'
alias: 'widget.murallist'
config: {
loadingText: 'Loading ...',
store: 'MuralStore'
itemTpl: [
'<div> Message: {message} </ div>
]
}
});
JSON returns my URL:
{
"rows": [
{
"lookup": "yyyy"
"dateTime", "10/10/1970"
"id": "1",
"message": "yyyy"
}
{
"lookup": "dsdfasfsadf"
"dateTime", "15/05/2012"
"id": "2",
"message": "dsdfasfsadf"
}
]
}
Does anyone know why the error, because JSON is in a valid format.
Thank you.
You're missing a comma in the middle :
{
"rows": [
{
"lookup": "yyyy"
"dateTime", "10/10/1970"
"id": "1",
"message": "yyyy"
},
{
"lookup": "dsdfasfsadf"
"dateTime", "15/05/2012"
"id": "2",
"message": "dsdfasfsadf"
}
]
}
My guess is that the service you're accessing returns JSON but not JSONP. Search the jsonp tag for "unexpected token". You'll find e.g. Why is this JSONP feed throwing "Unexpected Token" error?
Firstly, You'r missing ':' at many places and also ',' at the end of statements. It always good practise to use : before the property value and , at the end of statement.
Like this,
...
...
requires: [
'Projeto.model.Mural'
],
config: {
autoLoad: true,
model: 'Projeto.model.Mural',
storeId: 'MuralStore',
proxy : {
type:'jsonp',
},
....
....
Secondly, this error is occuring because your response is not a VALID jsonp response.
When I checked on jsonplint.com, it showed me this error
Invalid JSONP
No callback function defined
Improper or no closing
So, either you need to make sure that you have a valid callback function defined.
Otherwise, you could do one thing. Change the type:'jsonp' to type:'ajax' and that should resolve your problem without having to change anything else.
Since you are requesting it as jsonp, not just json, it expects your json to be enclosed in a callback function. Something like:
callback({
"rows": [
{
"lookup": "yyyy"
"dateTime", "10/10/1970"
"id": "1",
"message": "yyyy"
}
{
"lookup": "dsdfasfsadf"
"dateTime", "15/05/2012"
"id": "2",
"message": "dsdfasfsadf"
}
]
})