Relevant Http Response Code using graphql-js - graphql

Ok here's the thing, I'm trying to figure out how to deal with error handling with graphql-js. (In a case without Relay)
Not specific enough !? Ok so, since graphql-js is catching all errors thrown within resolve functions, I'm kind of confuse on how to deal properly with errors and http responses.
So I had few ideas and would like to know what you think about it !
Always return 200 OK with the graphql response even if containing errors. (Don't like that one)
Switch case on the result.errors[0] and return an http response in respect of the error, returning result.data if no errors. (which could end up being a veeeery long switch case)
Deal with the error handling in the resolve function and throw and object (e.g. { httpCode: 404, msg: 'No X found with the requested id' } )
In the express app.post function(or whatever web framework), having something like:
app.post('/graphql', function(req, res) {
let result = await graphql(req.body);
if(result.errors.size) {
let e = result.errors[0];
res.status(e.httpCode).send(e.msg);
}
res.json(result.data);
}
This doesn't currently work because of the way the error object is marshalled... or at least I haven't found how to get it out of graphql yet. I'm thinking of maybe looking into graphql-js source but I thought I better ask you guys first since I might be missing something obvious.
Obviously, a better idea is welcome !
Cheers :D

I am also trying to figure this out.
The best I have managed to come up with is throwing a custom error in my resolver. Check out apollo-errors. I am not sure if this is the best way, but it could work for you.

Related

How can I get Google Auth working with Laravel?

I'd like to know if there's an easy fix for this error that I'm getting while trying to add support for Google sign-in to my website, since I can only reproduce it while on a Laravel-based environment. Vanilla PHP applications do run just fine.
This is my relevant code:
if ($request->has('googleToken')) {
$client = new Google_Client(['client_id' => env('GOOGLE_PLATFORM_CLIENT_ID') ]);
$payload = $client->verifyIdToken($credentials['googleToken']);
if (!$payload) {
return response([ 'error' => 'Invalid token, please try using form-based authentication.' ], Response::HTTP_FAILED_DEPENDENCY);
}
$user['googleToken'] = $credentials['googleToken'];
}
I know I'm doing too relaxed validations, but please just focus on the fact that I'm just testing and I plan to change this code in the near future.
The code above, receives its data through an Axios PUT request from the frontend with the payload looking like this:
{
googleToken: "eyJhbGciOiJSUzI1NiIsImtpZCI6IjE5ZmUyYTdiNjc5NTIzOTYwNmNhMGE3NTA3OTRhN2JkOWZkOTU5NjEiLCJ0eXAiOiJKV1QifQ.eyJpc3MiOiJhY2NvdW50cy5nb29nbGUuY29tIiwiYXpwIjoiNTkyODkzNjE3ODYzLXRscDdvaDByaTk2dTZxZGxrOXYwbHAyanQyNDlkdDNsLmFwcHMuZ29vZ2xldXNlcmNvbnRlbnQuY29tIiwiYXVkIjoiNTkyODkzNjE3ODYzLXRscDdvaDByaTk2dTZxZGxrOXYwbHAyanQyNDlkdDNsLmFwcHMuZ29vZ2xldXNlcmNvbnRlbnQuY29tIiwic3ViIjoiMTE1NTg0MDg0NTE2OTMxOTQzODU..."
mailAddress: "user#mail.com"
}
The problem is that the payload would simply return false. I decided to try to investigate the issue, so I went to the definition of verifyIdToken contained within Google_Client and, from there, jumped over to the function that finally returns to its parent, which is verifyIdToken from the class Verify.
Inside of that class, there's a pretty loose try/catch block in which I decided to try adding a generic exception case so that I could quickly print the error message for debugging. I did, and this is the output I got:
OpenSSL unable to verify data: error:0909006C:PEM routines:get_name:no start line
This is what's failing internally, and from this point on, I don't really have an idea about how to proceed since the error feels very cryptic, or at least it's not in my field of knowledge.
The OpenSSL error you quoted indicates that your client was not able to read any/further PEM-encoded data. Refer to https://www.openssl.org/docs/man1.1.1/man3/PEM_read.html.
OpenSSL unable to verify data: error:0909006C:PEM routines:get_name:no start line
Here,
'PEM routines' represents the library within OpenSSL
'get_name' is the function
'no start line' is the reason
Is you client able to access the necessary certificates/keys?

Can we handle ngxs #Action errors via ofActionErrored() without going to default "ErrorHandler"?

I have an async ngxs action that throwsError().
I would like the default error handling mechanism to ignore this thrown error because I will be handling it in my code via ofActionErrored(). However, for other actions, default error handling should still take place.
Right now, both the ofActionErrored() and default error handling (via Angular/Ionic) tries to deal with the error.
The alternative I can think of is to dispatch Xxx_SUCCESS and Xxx_ERROR actions from within the initially dispatched action, something I would like to avoid if i can help it.
Advice appreciated.
There is a feature request that raised a similar concern at the NGXS repo. We've discussed in the core team meeting and we'll focus that for the next release. You can provide your feedback there: https://github.com/ngxs/store/issues/1691
You can use ofActionCompleted which as a result can provide the error, if there is one. An example taken from the code I am working on:
this.actions$.pipe(
ofActionCompleted(GetMe)
).subscribe((data) => {
const errorStatus = data.result.error['status'];
if (!data.result.successful && errorStatus === 403) {
this.snackbar.openFromComponent(TranslateSnakeBarComponent, {
data: {message: 'USER_DISABLED'}
});
}
});

Joomla 3.0 generic database error handling

Going from Joomla 2.5 to 3.0 with my extension, I'm struggling with how to do the DB error handling (since GetErrorNum is deprecated, see also Joomla! JDatabase::getErrorNum() is deprecated, use exception handling instead).
The way that seems to be the one to go according to the question linked above, is to add the following code for each db->query() code:
if (!$db->query()) {
throw new Exception($db->getErrorMsg());
}
In my opinion, that makes DB error handling more awkward than it was before. So far, I simply called a checkDBError() function after a DB call, which queried the ErrorNum and handled any possible error accordingly.
That was independent from how the DB query was actually triggered - there are different ways to do that, and different results on an error: $db->loadResult() returns null on error, $db->query() returns false. So there will now be different checks for different DB access types.
Isn't there any generic way to handle this, e.g. a way to tell Joomla to throw some exception on DB problems? Or do I have to write my own wrapper around the DatabaseDriver to achieve that? Or am I maybe missing something obvious?
Or should I just ignore the deprecation warning for now and continue with using getErrorNum()? I'd like to make my extension future-proof, but I also don't want to clutter it too much with awkward error handling logic.
Just found this discussion: https://groups.google.com/forum/#!msg/joomla-dev-general/O-Hp0L6UGcM/XuWLqu2vhzcJ
As I interpret it, there is that deprecation warning, but there is no proper replacement yet anyway...
Unless somebody points out any other proper documentation of how to do it in 3.0, I will keep to the getErrorNum method of doing stuff...
Get getErrorNum() function will solve your problem....
$result = $db->loadResult();
// Check for a database error.
if ($db->getErrorNum())
{
JFactory::getApplication()->enqueueMessage($db->getErrorMsg());
return false;
}

Uploadify v3 onUploadError howto

Been playing around with Uploadify v3 for few days now and just came to realize some of the codes have been rewritten, for example, onError is no longer existed, I am assuming it's been replaced by onUploadError.
What i am trying to achieve is to be able to return non-compliance error to users either through putting a message in the div (preferred method) or alert.
Looking at the closest solution How to trigger uploadify onError event handler, but it's outdated as it's for v2.
Using the same method as the outdated post up there, I have $("#fileInput").uploadify() with onUploadError added:
'onUploadError' : function(file,errorCode,errorMsg) {
var r = '<br />ERROR: ';
switch(errorMsg) {
case 405:
r += 'Invalid file type.';
break;
case 406:
r += 'Some other error.';
break;
}
alert(r);
setTimeout('$("#fileInput'+ ID + 'span.data").html("'+r+'");',111);
}
The problems I am having right now are:
Alert returns undefined using the codes above
setTimeout doesn't do anything
How can you solve these problems?
Maybe it's a little too late... but anyway I try to answer.
I'm also playing around with v3 of uploadify. onError() does no longer exists, it has been replaced by onUploadError(). The erroror object given by the old onError event does no longer exists. Now to check for the type of error you can switch on the errorCode argument (the second given in the callback), which is numeric. I've not found a table with all possible error codes, but doing some trials I discovered the following three error codes:
-200: HTTP errors (e.g. HTTP 500, 400, 404, etc.)
-220: IO errors (e.g. connection closed without response from the server, or errors while rading the source file from the user's PC)
-280: don't have actually fully understood what kind of errors they are, but is seems to be errors gracefully handled by uploadify. For example, if you try to add to the queue a file that is already in the queue, uploadify ask you whether you want to replace the file that's currently enqueued, or cancel the operation. If you cancel, an error is fired with code -280.
To check for the specific type of error, for example to get the specific HTTP error code (in case the error is an http error), you can check the error message, which is the third argument. This argument is a string, not a number, so you cannot use a switch .. case as in your example (or at least it's not that simple to use a switch .. case with strings). Simply use an if .. else if .. else.
Hope this can help...
I'm still looking for a complete list of the possible error codes given in the errorCode argument of the event handler. If someone knows, please tell me!

Is it a good or bad idea throwing Exceptions when validating data?

When validating data, I've gotten into a habit of doing the following:
Note: I don't really have individual booleans for each check. This is just for the example.
Another Note: any error handling during the tests are done properly. The ONLY exceptions thrown in the try-catch are my own.
try {
if (validCheckOne = false) {
throw new Exception("Check one is bad");
}
if (validCheckTwo = false) {
throw new Exception("Failed because of check2");
}
if(validCheckTen = false) {
throw new Exception("Yet another failure on your part: check10.");
}
} catch(Exception e) {
MessageBox.Show("Your stupid data is wrong! See for yourself: " + e.Message);
}
Is this bad practice? Does throwing Exceptions slow the program's execution or is inadvisable?
Personally I like throwing Exceptions for business rule validation (not so much for user input validation) because it forces the problem to be handled upstream. If my business objects returned some kind of validation result, it could be ignored by the caller. Call me a cowboy if you wish :)
Everyone here is repeating the phrase "exceptions are for exceptional circumstances", but that really doesn't give any understanding of why its bad to use them for unexceptional circumstances. I need more than that. Is the performance hit of throwing exceptions really that bad? Are there any benchmarks available?
I'm going to repeat the mantra here: throwing exceptions should be done in exceptional circumstances. Invalid entered data is really not that exceptional.
I support MusiGenesis's answer.
Additionally...
The performance of throwing an exception is a thousand instructions. It's nothing compared to end-user time, but in inner code it is slow.
An additional problem is that, using Exceptions, your validation is limited to reporting the first failure (and you will have to do it all again next time to find the next failure).
In addition to the oft-repeated statement that "exceptions are for exceptional circumstances", here's an additionally clarifying rule I've come to like:
If the user caused it, it's not exceptional.
Exceptions are for system-side things (servers going down, resources being unavailable), not for the user doing odd things, because all users do odd things.
It depends - if you are expecting the data to be there and NOT having the data is unexpected, then throwing an exception is OK. Throwing an exception is very expensive (slow) but is the best way to handle unexpected circumstances.
In the title you call it "validating" data. That can happen on several levels. In (near) the GUI where you are checking user entered data, you should be expecting errors and have ways to report the errors back. Exceptions are inappropriate in this case.
But Data Validation can also happen at other boundaries, say between business-rule classes. There, errors in the data are uncommon and unexpected. You should throw when you detect one.
So maybe in some languages exception throwing and catching is "costly" but in other languages, throwing and catching exceptions is exactly what's called for.
In Smalltalk, for example, one could quickly build a multi-tiered exception catching solution. The validation pass could collect up any number of exceptions representing EVERYTHING that's wrong with a particular input data set. Then it would throw them ALL up to a higher-level catcher, responsible for formatting up a human-readable explanation of, again, EVERYTHING that was wrong with the input. In turn it would throw a single exception further up the chain, along with that formatted explanation.
So... I guess what I'm saying is, exceptions are only bad to throw if you've got no exception handling architecture supporting catching them and doing reasonable things with them, and all your catcher is going to do is EXIT or do something else equally inappropriate.
This is bad behavior. Exceptions are for Exceptional conditions. They take resources to generate the stack etc. Exceptions should not be used to dictate process flow.
In general it is inadvisable to use Exceptions to implement conditional flow. It would be better to do something like this
error = false;
while(true) {
if(validCheckOne == false) {
msg = "Check one is bad";
error = true;
break;
}
if(validCheckTwo == false) {
msg = "Check two is bad";
error = true;
break;
}
...
break;
}
if (error) {
..
}
You should throw an exception when there is a situation you can't do nothing about it. Higher layers of software would have a chance to catch the exception and do something about it - even if that is simply crashing the application.
I would suggest that using exceptions as described in the question (for flow control within a function) is wrong not usually the best idea. I'd go further and saying validation throwing exceptions isn't the best approach; instead return a Boolean and store a list of validation error messages that can be accessed. An accompanying save method could/should throw an exception if it is called on an invalid object.
Thus if validate fails validation error messages can be displayed to the user (logged, returned. whatever). If validation passes then you can call save.
If you call save on an invalid object then get get an appropriate exception.
Another potential problem with your example code (depending on requirements of course) is it only throws the first validation error that occurs. Imagine this from a users POV:
Click save
Get an error message
Correct error
Click save again
Get a different error message. Annoying.
As a user I'd prefer to get all validation errors returned at once so I can correct them all before trying again.
I generally agree with the "exceptions should be exceptional" rule, but I might make an exception (ha!) for Python, where it can be both efficient and considered good practice to use try ... except to control flow.
See Using Exceptions For Other Purposes, for example.
This question is still interesting, mainly because of the answers.
When it comes to exception, there is a lot of arguments involved. We can defend a point to any direction we want to, from performance to exception philosophy. And they all sounds right to me.
But sometimes we have to stick to a direction. In this case, I think it's the validation itself.
When we want to validate something we also want to know (to log, or to show the user) whats wrong when the parameter is invalid. Even thought there are layers of validation such as Business Validation mixed with User Input validations.
For instance, when dealing with user input, a lot of weird cases can happen. A pasted data from a website full of hidden char (\t \n etc), typos, and a really huge kinds of cases that a specific exception could allow further analysis or message to the uses much more precisely than a simple "false" return.
When you go to the grocery and ask the seller if he's got cheese, and the seller replies with no, would that be an unexpected or exceptional response?
What about if you do the same but the seller just looks at you and does not respond!
Another example, you are talking to your friend and ask if there is something wrong, you may get 2 responses:
They tell you that they are sad because of something.
Or they just look at you and say nothing, turn their back and walk away and you are sure that this means you're in deep trouble :)
Same way with exceptions, unexpected behavior is an exception, but an invalid but expected response should not - IMHO - throw exceptions.
I often write similar code for validation, especially in express.js, and similar request/response loop style applications. When something is invalid, I throw a ValidationError, it's caught by the top level error handler, which knows to send a 422 response with the additional information that's attached to the ValidationError.
It's a very convenient way to handle validation. You don't have to pass around an error object (potentially up through a dozen stack frames, in some cases). And it's a simple and consistent way to trigger an invalid input response. I haven't experienced any serious problems with this approach.
I've thought about the "don't use exceptions for flow control" maxim in relation to this practice, and decided the benefits outweigh any disadvantages. I would say if you understand the reasoning behind "don't use exceptions for flow control", but you determine that it's a good idea anyway in a certain case, then go ahead and do it. We don't need to be too dogmatic about these things.
Throwing exceptions is relatively slow, but that will only matter if you're doing it repeatedly in a loop.
It really only matters if your data validation is in a tight loop. For most cases, it doesn't matter what you choose as long as you are consistent in your code.
If you have a lot of code that looks like your sample above then you might want to clean it up by introducing a helper method to throw...
private void throwIf( bool condition, String message )
{
if( condition )
throw new ApplicationException( message );
}
(also, doing this will help zero in on errors such as "validCheckOne = false" versus "validCheckOne == false" :)
Well, i know it's an old question. But i'll let my opinion here for the googler's who falled here like me:
If you are using a language with a bad try/catch support AVOID
THROWING exceptions for data validation;
DO NOT THROW a exception that will not be handled by the caller or
alserwhere;
DO NOT THROW a exception if you need to validate the rest of the received data;
You can THROW a exception in cases where the code block cannot continue
without the invalid data; And if you do not interrupt the process you
can get a unhandled exception;
An example:
/*
* Here it's a common problem i have: Someone pass a list of products i need to
* retrieve from the database and update some information;
*/
//This is a class to represent the product
function Product(id, name, price) {
this.id = id;
this.name = name;
this.price = price;
}
//This is an example function to retrieve the product from the database
function findProductInDatabase(productId) {
//If the product exists on the database, the function will return it
if (productId == 12) {
var product = new Product(12, "Book", 20.5);
return product;
}
//If the product do not exists, it will return null
return null;
}
//This is a function that will receive the productID and will update the received parameters
function updateProduct(productId, newProductName, newProductPrice) {
var productFromDatabase = null;
var errorMessage = "";
//Retrieve the product
productFromDatabase = findProductInDatabase(productId);
//If the product do not exist, i need to interrupt de method imediatily and alert the caller
if (!productFromDatabase) {
throw "Product not found";
}
//Validate the other parameters, but in this case i can validate all the parameters
if (newProductPrice < 10) {
errorMessage += "the price is too low";
}
if (newProductName.includes("<")) {
//If already has a error message in the variable i append " and " to the message make sense
if (errorMessage) {
errorMessage += " and ";
}
errorMessage += "the new name has invalid characters";
}
if (errorMessage) {
//if theres any error, i will throw a exception with the messages
throw errorMessage;
}
}
//This parte is where the method id called;
try {
updateProduct(9, "Book", 10.5);
} catch (exception) {
console.log("Case 1: " + exception);
}
try {
updateProduct(12, "<Book", 9);
} catch (exception) {
console.log("Case 2: " + exception);
}
In test, sure, but in a live environment, you'd hope they're never raised.
You'd hope to refactor your code to the extent that all data into your system are validated at source, and either the user, or the system that generated the input to your system, is notified of the issue.
Exceptions should occur if you've missed something and should be a fallback that is handled gracefully.
You could store anything that's causing these exceptions separately, so that they don't make it into your system without being checked over first.
You don't want, e.g. an invalid value that falls outside a range of values to skew your results.

Resources