How to I can custom exception message from FileInterceptor? - file

I want custom exception from FileInterceptor.
Here my lines of code:
#Post('single')
#UseInterceptors(
FileInterceptor('file', { limits: {
files: 1
}}),
)
async uploadFile(#UploadedFile() file, #GetUser('id') userId: number, #Body() dto) {
this.logger.log('Upload file');
file.createdBy = userId;
file.oldFileName = dto.oldFileName;
return this.client.send('upload_file', file);
}
I pass in body with file attribute, it is 1 array files (there are 2 files)
I got message:
{
"response": {
"statusCode": 400,
"message": "Too many files",
"error": "Bad Request"
},
"status": 400,
"message": "Too many files",
"name": "BadRequestException"
}
I want custom that message like to this:
{
"code": 400,
"message": "Too many files"
}
Please help me a solution. Thanks

you can try this to custom your error

Related

Find number of occurrences of a certain value in an object - Typescript

I have a nested object and I need to calculate the number of times the 'status' field has a value of 2 and a value of -1. This is what I have.I am open to using lodash as well.
const data = {
"file1": {
"file": {
"path": "file1"
},
"loadedBytes": 1,
"status": 2,
"error": null
},
"file2": {
"file": {
"path": "file2"
},
"loadedBytes": 1,
"status": -1,
"error": "Unexpected error occured - please try again. If error persists, please contact"
},
"file3": {
"file": {
"path": "file3"
},
"loadedBytes": 1,
"status": 2,
"error": null
},
"file4": {
"file": {
"path": "file4"
},
"loadedBytes": 1,
"status": 2,
"error": null
},
"file5": {
"file": {
"path": "file5"
},
"loadedBytes": 1,
"status": -1,
"error": "Unexpected error occured - please try again. If error persists, please contact Trinity"
},
"file6": {
"file": {
"path": "file6"
},
"loadedBytes": 1,
"status": 1,
"error": ""
},
"file7": {
"file": {
"path": "file7"
},
"loadedBytes": 1,
"status": -1,
"error": "Unexpected error occured - please try again. If error persists, please contact Trinity"
},
"file8": {
"file": {
"path": "file8"
},
"loadedBytes": 1,
"status": 1,
"error": ""
},
"file9": {
"file": {
"path": "file9"
},
"loadedBytes": 1,
"status": -1,
"error": "Unexpected error occured - please try again. If error persists, please contact Trinity"
}
}
var countStatus = (status) => Object.values(data).reduce(function(n, i) {
return n + (i.status === status);
}, 0);
console.log({
countSuccess: countStatus(2),
countFailure: countStatus(-1)
})
Is there a better way to achieve the same result? Please note, I am using Typescript and the addition inside the reduce method causes a type error shown here. Please advice.
The error given by TypeScript can be avoided by turning the boolean expression to number explicitly, using the unary plus:
return n + +(i.status === status);
For the rest your solution is fine.
You can use _.countBy() to get an object with the counts of all statuses, and then get the ones you want by destructuring the object (stackblitz):
const data = {"file1":{"file":{"path":"file1"},"loadedBytes":1,"status":2,"error":null},"file2":{"file":{"path":"file2"},"loadedBytes":1,"status":-1,"error":"Unexpected error occured - please try again. If error persists, please contact"},"file3":{"file":{"path":"file3"},"loadedBytes":1,"status":2,"error":null},"file4":{"file":{"path":"file4"},"loadedBytes":1,"status":2,"error":null},"file5":{"file":{"path":"file5"},"loadedBytes":1,"status":-1,"error":"Unexpected error occured - please try again. If error persists, please contact Trinity"},"file6":{"file":{"path":"file6"},"loadedBytes":1,"status":1,"error":""},"file7":{"file":{"path":"file7"},"loadedBytes":1,"status":-1,"error":"Unexpected error occured - please try again. If error persists, please contact Trinity"},"file8":{"file":{"path":"file8"},"loadedBytes":1,"status":1,"error":""},"file9":{"file":{"path":"file9"},"loadedBytes":1,"status":-1,"error":"Unexpected error occured - please try again. If error persists, please contact Trinity"}}
const { '2': countSuccess, '-1': countFailure } = _.countBy(data, 'status')
console.log({ countSuccess, countFailure })
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.20/lodash.min.js" integrity="sha512-90vH1Z83AJY9DmlWa8WkjkV79yfS2n2Oxhsi2dZbIv0nC4E6m5AbH8Nh156kkM7JePmqD6tcZsfad1ueoaovww==" crossorigin="anonymous"></script>

AJV validator and custom or user-friendly error message

I have the following schema and json to validate using ajv. I am developing a REST API that takes a JSON and gets validated against the schema and it returns the error (400- with the ajv error) or (200 - when successfully validated)
const schema = {
"$schema": "http://json-schema.org/draft-07/schema#",
"type": "object",
"required": [ "countries" ],
"definitions": {
"europeDef": {
"type": "object",
"required": ["type"],
"properties": { "type": {"const": "europe"} }
},
"asiaDef": {
"type": "object",
"required": ["type"],
"properties": { "type": {"const": "asia"} }
}
},
"properties": {
"countries": {
"type": "array",
"items": {
"oneOf":[
{ "$ref": "#/definitions/europeDef" },
{ "$ref": "#/definitions/asiaDef"}
]
}
}
}
}
const data = {
"countries":[
{"type": "asia1"},
{"type": "europe1"}
]
}
const isValid = ajv.validate(schema, data); //schema, data
if(! isValid){
console.log(ajv.errors);
}
and the error is:
[ { keyword: 'const',
dataPath: '/countries/0/type',
schemaPath: '#/definitions/europeDef/properties/type/const',
params: { allowedValue: 'europe' },
message: 'should be equal to constant' },
{ keyword: 'const',
dataPath: '/countries/0/type',
schemaPath: '#/definitions/asiaDef/properties/type/const',
params: { allowedValue: 'asia' },
message: 'should be equal to constant' },
{ keyword: 'oneOf',
dataPath: '/countries/0',
schemaPath: '#/properties/countries/items/oneOf',
params: { passingSchemas: null },
message: 'should match exactly one schema in oneOf' },
{ keyword: 'const',
dataPath: '/countries/1/type',
schemaPath: '#/definitions/europeDef/properties/type/const',
params: { allowedValue: 'europe' },
message: 'should be equal to constant' },
{ keyword: 'const',
dataPath: '/countries/1/type',
schemaPath: '#/definitions/asiaDef/properties/type/const',
params: { allowedValue: 'asia' },
message: 'should be equal to constant' },
{ keyword: 'oneOf',
dataPath: '/countries/1',
schemaPath: '#/properties/countries/items/oneOf',
params: { passingSchemas: null },
message: 'should match exactly one schema in oneOf' } ]
I know why the error is appearing (reason: as I have used 'asia1' & 'europe1' and it is not conforming the schema standard)
My question is, as I have derived this schema so I can pretty much understand the error. But for a third person it would definitely take some time to figure it out (and it may take more time, if the schema/errors are more complex).
If I returned that whole error message as a response as it is, it will be more complex error message to understand and to present to the enduser.
So, Is there any way by which I can provide more meaningful & user friendly error message to understand ?
ex: Invalid countries values found in JSON
I have checked: ajv-errors, better-ajv-errors but they are not providing the exact way I want?
Can someone suggest how to do that in a more user friendly way or any alternative mechanism?
I am using below code for generating the human readable error message
let msg: string = "Wrong body" // fallback error message;
if (errors && errors.length > 0) {
const error = errors[0];
msg = `${error.instancePath} ${error.message}`;
}
res.status(4xx).json({
errorMsg: msg,
});
I am using below dependencies to generate the validate functions in runtime with the below code
"dependencies": {
"ajv": "^8.11.0",
... // other dependencies
}
"devDependencies": {
"ajv-cli": "^5.0.0"
}
Below code gets run before project build and hence creating runtime generated validation files
const ajv = new Ajv({
schemas: schemas, // list of parsed json *.json schemas
code: { source: true, esm: true },
});
let moduleCode = standaloneCode(ajv);
Below is the few examples of error messaged diaplayed
Case of missing property:
"/items/0/price must have required property 'currency_code'"
Case of additional property: "/address must NOT have additional properties"
Case when quantity is fraction(allowed is +ve number): "/items/0/quantity must be integer"
Case when quantity is -ve(allowed is +ve number): "/items/0/quantity must be >= 1"
Case when passed value is not allowed(case of the enum): /items/0/price/currency_code must be equal to one of the allowed values

Gmail API, cannot remove "SENT" label from email

I cannot remove the "SENT" label from any email.
I used PHP classes but it doesn't matter because it occurs even in test page of users_messages.modify.
This is my PHP code:
$mods = new Google_Service_Gmail_ModifyMessageRequest();
$mods->setAddLabelIds(['UNREAD']);
$mods->setRemoveLabelIds('SENT');
$message = $gmailService->users_messages->modify($userId, $messageId, $mods);
I think it could be a general Gmail API error.
I can remove all the others labels but not "SENT". Try it with the follow "Request body":
{
"removeLabelIds": ["SENT"],
"addLabelIds": ["UNREAD"]
}
I got this ERROR 400 reply from the server:
{
"error": {
"errors": [
{
"domain": "global",
"reason": "invalidArgument",
"message": "Invalid label: SENT"
}
],
"code": 400,
"message": "Invalid label: SENT"
}
}
According to this google forum, there is no way of removing the SENT label in Gmail API.

Gmail api returns 404 error when calling message.get

Gmail API history.list is returning messageId's that return 404 when message.get is called.
I call history.list with "INBOX" label and "history/messagesAdded" fields. I then call message.get with each of the messageId's returned. Some of them return valid messages, others return the following exception:
Google_Service_Exception
{
"error": {
"errors": [
{
"domain": "global",
"reason": "notFound",
"message": "Not Found"
}
],
"code": 404,
"message": "Not Found"
}
}
What would cause this? It seems like we just retrieved the messageId there isn't enough time for them to now be permanently deleted.
As explained in the comments, this can happen if the message was deleted. This can be checked in the messagesDeleted array return by gmail's history.list, just make sure you send the appropriate historyTypes (or doesn't send any at all).
{
"history": [
{
"id": "69014",
"messagesAdded": [
{
"message": {
"id": "165a2cd1a5b308b9",
"threadId": "1659e85b88e80e7b",
}
}
]
},
{
"id": "69024",
"messagesDeleted": [
{
"message": {
"id": "165a2cd1a5b308b9",
"threadId": "1659e85b88e80e7b",
}
}
]
}
}

Server side errors handling with angular-formly

I'm looking for solution on how I can display errors that the server respond, this is the respond for every invalid submission so I want to make the error handler in the app level and not in a controller.
I want to display the errors both on the FORM level and on the field level.
I have a REST API that in case of error return the following JSON object:
{
"message": "Validation error: Validation notEmpty failed,\nValidation error: Validation isEmail failed",
"errors": [
{
"field": "username",
"message": "Validation notEmpty failed"
},
{
"field": "email",
"message": "Validation isEmail failed"
}
]
}
How can I create a service that display the errors in case there is any?
Thanks
So, i created this for another answer. Let me know if this sort of a setup works for you. Here, the error is intended to be displayed on response from the server after button click. You can modify it accordingly.
I have given the field a custom template as follows:
formlyConfigProvider.setWrapper({
name: 'inputWrapper',
template: '<div ng-class="to.changeColor==\'red\'? \'redBorder\' : \'otherBorder\'"><formly-transclude></formly-transclude>{{to.keyVal}}</div>'
});
The form elements are defined through a schema format to allow each element to be individually accessed.
vm.schema={
"schema": {
"coolValue" : [{
"key": "coolValue",
"type": "input",
"wrapper": ['inputWrapper'],
"templateOptions": {
"type" : "text",
"label": 'Cool Value',
"keyVal":"",
"changeColor":"green"
}
}]
}
};
Finally, the onSubmit function
function onSubmit() {
//Do whatever you want here
//Let's say your server returns an error "iNVALID Credentials"
var response={
"error": {
"errors": [
{
"domain": "global",
"reason": "authError",
"message": "Invalid Credentials",
"locationType": "header",
"location": "Authorization",
}
],
"code": 401,
"message": "Invalid Credentials"
}
};
vm.schema.schema.coolValue[0].templateOptions.changeColor="red";
vm.schema.schema.coolValue[0].templateOptions.keyVal=response.error.message;
}
});
You can essentially pass any error message or response from the server here.
The CSS contains a class to add a red border to the field.You are free to disable this.Feel free to ping if you need anything in this area as well.
Here is a DEMO

Resources