I am using async in nodeJS, and in my final callback I am handling the error and trying to send it back to my angular controller.
function (err, data) {
if (err) {
console.log(err);
res.status(500).send({ err : err});
}
else {
res.json({data: data});
}
});
Now the error in the console is.
[Error: Username is already in use]
I am not able to get this particular error in my angular controller I tried sending the error in all combinations such as .
res.status(500).send({ err : err[0]});
res.status(500).send({ err : err.Error});
This is what I get in my front end.
Object {data: Object, status: 500, config: Object, statusText: "Internal Server Error"}
config
:
Object
data
:
Object
err
:
Object
__proto__
:
Object
__proto__
:
Object
headers
:
(d)
status
:
500
statusText
:
"Internal Server Error"
How can I bring that username in use error to my front End.
500 errors are usually reserved for Server errors, and not for scenarios like the one you have described. Server errors should be handled by your server and elegantly presented to your front end. Client errors should be in the 400s. Why don't you try a 409 or a 400:
res.status(409).json({error: "Username is already taken"});
Look at HTTP Status codes for more:
409 Conflict
The request could not be completed due to a conflict with the current state of the resource. This code is only allowed in situations where it is expected that the user might be able to resolve the conflict and resubmit the request. The response body SHOULD include enough information for the user to recognize the source of the conflict. Ideally, the response entity would include enough information for the user or user agent to fix the problem; however, that might not be possible and is not required.
Conflicts are most likely to occur in response to a PUT request. For example, if versioning were being used and the entity being PUT included changes to a resource which conflict with those made by an earlier (third-party) request, the server might use the 409 response to indicate that it can't complete the request. In this case, the response entity would likely contain a list of the differences between the two versions in a format defined by the response Content-Type.
Note: Also, as a good practice, make sure you return your res. functions, for predictable flow of control, like so:
return res.status(409).json({error: "Username is already taken"});
Related
I have a web api which is using express and NodeJs. This sounds really basic but I could not found a solution. How can I return a response with http status code and Json object?
For example:
res.send(500, {success: false, error 'Sorry, error'});
Even if I return an error http response code, I would like to return a json object. I am trying to use some request methods, but no one of them give the option to set http status code and json object.
I am pretty sure that I might be missing something, because this is really basic for a web api framework.
Thanks in advance.
As per the Express (Version 4+) docs, you can use:
res.status(400);
res.send('Response');
You can add a status code with your response like this
res.status(500).json({success: false, error 'Sorry, error'});
You could do something like this
res.json({ user: 'tobi' })//sends a json only
res.status(500).json({ error: 'message' })//sends json with status code
I also had the same issue but I finally solved it with something very simple
res.status(400).json({error:"error message here"})
This worked although at the Network on chrome 200 appeared
I am building a WebAPI as a learning project and attempting to use best practices. My first attempt is a authentication API, which takes an authentication object (JSON):
{
username: myusername,
password: mypassword
}
it calls my API on /api/authenticate as a POST, passing the object.
In my .Net code, I do some checks, and if the username/password pass, I create a jwt token, and return it with roles. My API returns a 200 with the token in the body (response in Chrome developer tools shows "ey.....", which is my jwt).
If I get an invalid username/password, I return a 401.
I'm not sure this is right. Should I rather return a 200 - and some other payload in the body? (Not sure what), and then should my successful login return JSON, such as:
{
success: true,
error: null
token: "ey.....",
}
A failed login return:
{
success: false,
error: null
token: null,
}
and then an error:
{
success: false,
error: 500
token: null,
}
And then client side code uses that to decide what to do? I'm trying to work on a best practice here to learn how to handle this in WebAPI.
I don't think there is really a "best practice" here. Some APIs return an error object like you did with JSON. That's completely fine. Other APIs return HTTP errors (401, 500, etc...). Other APIs return both. There are pros and cons to each method, so choose whatever you like or suits your needs best.
If you go with the first method, don't limit yourself to returning HTTP codes. Instead, return codes that give you and the consumers of your API more specific references to the errors. For example, code 401 doesn't tell me why the authentication failed. Probably that's fine for security, but I'm only using it here as an example, so instead you can return code 1001 for incorrect credentials, 1002 for an account that is locked, 1003 for an account that is pending approval, etc...
Pros of the first method: the API consumer can handle everything in the same code using a simple if...else or switch logic. It is also easier to test. The cons: you still need to use try...catch, because the request to the API may still fail, so the consumer code will have the above logic plus the try...catch logic.
Pros of the second method: it is more inline with the way we usually do things. Use try...catch to handle all errors, and the code inside will only be for the successful path. The cons: a little harder to test and you're stuck with the HTTP error codes.
The third method is a combination of the two. In some cases it is probably an overkill and adds some unnecessary complexity and repetition, but in other cases it can combine the benefits of the two worlds.
Here I give a different way of returning response message...
I hope, This will help you in returning the response message...
// For login success
In the below code, it shows the success response...
return Content(HttpStatusCode.Ok, error); This will helps to return the status code in the header of the Postman Tool.
if (result == null)
{
var error = new
{
Success = "true",
Token = "your token"
};
return Content(HttpStatusCode.Ok, error);
}
//for Unauthorized user login
In the below code, it shows the Unsuccess login response...
Here we can mention the error status to the user in response...
return Content(HttpStatusCode.Unauthorised, error); This will helps to return the status code in the header of the Postman Tool.
if (result == some condition)
{
var error = new
{
Error = new
{
StatusCode = HttpStatusCode.Unauthorised,
Message = "Invalid Credential...! ",
InternalMessage = "Some message"
}
};
return Content(HttpStatusCode.Unauthorised, error);
}
// for error
In the below code, it shows the Unsuccess login response...
Here we can mention the error status to the user in response...
return Content(HttpStatusCode.InternalServerError, error); This will helps to return the status code in the header of the Postman Tool.
if (result == somecondition)
{
var error = new
{
Error = new
{
StatusCode = HttpStatusCode.InternalServerError,
Message = "Error in functionality...!",
InternalMessage = "Some message"
}
};
return Content(HttpStatusCode.InternalServerError, error);
}
I come from Mandrill which gives me error messages such as success, rejected or invalid in the callback corresponding to the callback in the source code snippet below. In Mandrill, for example, in the Send call, you can get success JSON responses such as:
[
{
"email": "recipient.email#example.com",
"status": "sent",
"reject_reason": "hard-bounce",
"_id": "abc123abc123abc123abc123abc123"
}
]
or error JSON responses such as:
{
"status": "error",
"code": 12,
"name": "Unknown_Subaccount",
"message": "No subaccount exists with the id 'customer-123'"
}
I saw the code here from the official SendGrid Node.js API implementation and this page about the SendGrid Web API v2 and I am wondering whether there can be JSON responses (in the json variable below) such as { message: 'error', ... }, for example when the err variable below is null.
My code looks like this (it is inspired from this page):
sendgrid.send(email, function (err, json) {
if (err) { return console.error(err); }
console.log(json);
});
In this code, from my tests,
err can take the values [Error: Missing email body], [Error: Missing subject] etc. or null. When it is null then there is no error.
json always has the value { message: 'success' } when there is no error and null when there is an error.
These are some of the web pages I have read but they did not help me:
1
Google queries I tried:
sendgrid message success
sendgrid web api response
So my question is, what are the possible error messages in the response JSON (in the value of the message property in the given example of response JSON) when sending email using the official SendGrid Node.js API? I think about something similar to rejected from Mandrill, without using a webhook.
Mandrill has a "synchronous" sending mode, which it sounds like you were using. SendGrid does not. We accept the API request (as long as it is well-formed), then hand it off for processing. So the answer to your question is that there are no possible email-related errors in the response payload, only errors when the request itself is bad.
The next version of this endpoint will have better validation and error reporting, but will still be entirely async. However, the response body will return a message ID that you can use to check status later without having to use a webhook. Stay tuned for that.
Background Info
I have a new project I'm working on that will provide multiple different (optional) packages that can be installed, all of which are in addition to the core package (only manual package). The other packages just interact with the core.
The project is just meant to keep track of lists of data (not very specific, I know, but these details aren't needed). The add-on packages determine HOW the lists of data are interacted with. The core package just consists of all the main JS functionality and database models, and authentication. The other packages tie into those.
Lets say you want to just have it as a standard web page, you can install the webui package, which will tie into the core, and create a web app for it
If you want to create an API, you can install the restapi package, which creates the RESTful interface; You can also install the spaui package which will interact with the RESTful interface, which gets the data from the core
These addon packages I will call "facade" packages. All you really need to extrapolate from the above is that the core is a separate package from the facade packages, and it handles the core functionality (Database stuff, authentication, authorization, etc)
Problem
The core can use promises or callbacks, and it returns exceptions for failures, then whatever facade package is used to interact with the core will handle the exceptions/errors (showing an HTTP error page, returning a RESTful error result, etc).
Since the package that handles the errors is different than the package that returns the errors, there needs to be a systematic way of knowing what type of error was returned, so it can be dealt with properly (EG: The webui/restui packages should know if it needs to show a HTTP 500, a HTTP 403, HTTP 409, etc). Obviously of the core just returns new Error('Something broke'), then the facade packages don't really know what type of error it is, unless they have the text saved somewhere and can match it up with an error code.
Question
Whats the best way to handle this? I haven't been able to find anything that accomplishes this exactly how I want..
I eventually started working on my own attempt.. (below)
My Possible Solution (If this is sufficient, just confirm)
I created a new AppError exception type, and instead of returning AppError exceptions with simple strings, you provide an error code which will associate that exception with the error message, error type, etc.
Here is an example usage of the AppError exception:
exports.createThing = ( name, data ) => {
return new Promise( ( res, rej ) => {
if( doesItExist( name ) )
return rej( new AppError( 'document.create.duplicateName' ) )
// Other stuff...
})
}
Now inside the AppError exception method, it takes the code and looks inside a list of exceptions (the code should be the key inside an object of exception data).
Heres an example of what the exception data object for the above exception would contain:
module.exports = {
'document.create.duplicateName': {
type: 'DocumentConflict',
message: 'Failed to create new document',
detail: 'The document name specified already exists, try another one'
}
}
Example Usage: Lets say we try to execute createThing with an already existing name (From within the webui package):
CorePackage.createThing( 'foobar', 'some data' )
.catch( err => {
/*
The err is now an instance of AppError
err.type -> DocumentConflict
err.message -> Failed to create new document
err.detail -> The document name specified already exists, try another one
*/
})
From here, it's as simple as associating the err.type value with a suitable HTTP error code! (which would probably be HTTP 409 Conflict). Obviously these associations can be kept in an object, making it easy to just retrieve the correct error code for any of the error type values returned. Then the text for the error code is right there in err.message and err.detail
This also makes it easy to introduce some type of locale into the application, as the error, as all that needs to be done is to edit the exception data object.
End of post
So if you think my solution above is a sufficient one, and you cant think of any problems, then please say so. Id like to know if it is or if it isn't. Even if you can't think of a proper solution, but you just know the one I created wont work, share that as well.
If you have an alternative solution, then that would work just as well!
Thanks
I think there are two basic ways to approach this:
code property: Create a new \Error object and assign the code property with information about the error. For example:
var err = new Error('Message');
err.code = "DocumentConflict";
Custom error objects. You could have a seperate Error object per error type that you have. For example, rather than having just AppError, you can have DocumentConflict error.
For projects where I am creating a RESTful API, I like to think in terms of error codes. For most projects, the endpoints will return one of the following codes:
400 (Bad Request)
401 (Credentials Error)
403 (Forbidden)
404 (Not Found).
500 (Internal Server Error).
These then become 'standard' types of Error that I pass around the application. A normal Error object is interpretated as an internal server error, so this will always pass 500 to the endpoint.
For example,
CredentialsError = function (message) {
Error.call(this, arguments);
Error.captureStackTrace(this, this.constructor);
this.message = message;
};
util.inherits(CredentialsError, Error);
CredentialsError.prototype.name = "CredentialsError";
And then just return/throw a new CredentialsError("Invalid password") object as necessary. To check the type of object, you can use instanceof. With Express, for example, you can have an error handler similar to the following:
app.use(function(err, req, res, next) {
var status;
if (err instanceof error.FieldError) {
status = 400;
} else if (err instanceof error.CredentialsError) {
status = 401;
/* etc */
} else {
status = 500;
}
if (status !== 500) {
res.status(status).send(JSON.stringify(
err,
null,
4
));
} else {
// for 500, do not output the error!
console.error(err.stack);
res.status(500).send({
message: "Internal Server Error"
});
}
});
It is also worth noting that you can defined your custom error object constructors to take more than just strings. For example, you can pass objects into a BadRequestError constructor to provide field-level error detail.
Now, in most cases, you can just propagate the errors and the response to the endpoint will make sense. However, there are cases where you want to transmute the type of error. For example, if you have a login endpoint, you might do a request to findUserByEmailAddress(). This could return a NotFoundError object, but you want to capture this in the signIn() function and transmute it to a CredentialsError.
An error is being passed by the callback in my request function. I am trying to determine under what conditions an error is passed to the callback.
var request = require('request');
request('http://www.google.com', function (error, response, body) {
if(error){
//why or when would an error be created?
}
else if (response.statusCode == 200) {
console.log(body) // Show the HTML for the Google homepage.
}
else{
// when would this happen ?
}
})
the documentation doesn't seem to cover what conditions will cause an error object to be created and passed. Right now I just assume anything but a 200 or 300 will cause an error to be created, but I am just guessing.
request library uses the node.js http module internally for making GET request. From it's doc:
If any error is encountered during the request (be that with DNS
resolution, TCP level errors, or actual HTTP parse errors) an 'error'
event is emitted on the returned request object.
I guess you have to go though the http module source to exactly find out what are the errors.