react-apollo Error: Network error: Unexpected token < in JSON at position 1 - react-native

I want to send a request to this server via Apollo and get a query :
const client = new ApolloClient({
link: new HttpLink({
uri:'http://mfapat.com/graphql/mfaapp/'}),
cache: new InMemoryCache()
})
const FeedQuery = gql
query{
allFmr{
fmrId,
name,
studio,
bedRm1,
bedRm2,
bedRm3,
bedRm4
}
}
`
But I'm facing this error message:
Unhandled (in react-apollo:Apollo(FMRScreen)) Error: Network error: Unexpected token < in JSON at position 1
at new ApolloError (http://localhost:8081/index.bundle?platform=android&dev=true&minify=false:109336:32)
at ObservableQuery.currentResult (http://localhost:8081/index.bundle?platform=android&dev=true&minify=false:109447:28)
at GraphQL.dataForChild (http://localhost:8081/index.bundle?platform=android&dev=true&minify=false:103192:66)
at GraphQL.render (http://localhost:8081/index.bundle?platform=android&dev=true&minify=false:103243:37)
....
But I can easily open "http://mfapat.com/graphql/mfaapp/" in my browser and get a query. Does anyone know where the problem is?

Right now, Apollo treats everything sent from the server as JSON. However, if there is an error, then your server might be sending HTML to show a basic error page.
To see the error, open your dev tools, and look at the network tab. This shows an example 401 error:
As you can see, if you were to parse this as JSON you would stumble over the first character: < which is where our error message comes from.
Reading the specific error sent enables you to fix the bug.
To fix the general error, configure your server to send JSON on HTTP errors, not HTML code. This should allow Apollo to parse it and display a sensible error page.
EDIT: Also see this discussion - hopefully they will change the default Apollo behavior, or at least provide useful discussion.

Base on #eedrah answer, I managed to resolve this issue by using an error handler middleware to always return erros as JSONs, so that Apollo Client error link can parse the errors.
// On Apollo server
// Error handler
const errorHandler = (err, req, res, next) => {
if (res.headersSent) {
return next(err);
}
const { status } = err;
res.status(status).json(err);
};
app.use(errorHandler);

Related

Axios triggering weird in React native app

Hello i have a weird thing going on,im using axios in order to send post-get http request for my app.The thing is that axios in my pc working good but in my laptop need console.log("") before axios request i dont know why.This happens in all my files.
It gives me this error : Possible Unhandled Promise Rejection (id : 0 ):
[Axios error: Request failed with statis code 404]
Here is my code :
function getProfile(){
try{
//console.log("") <-------------------------- Here i put it
axios.post(URL+'/checkData',
{
usernameCheckAXIOS : username,
passwordCheckAXIOS : password,
})
.then((response)=>{
console.log(response.data)
setProfile(response.data);
if(response.data.responseOfProfile == false){
Alert.alert("Access Dinied")
}
else{
navigation.navigate('Home')
}
})
}catch(error){}
}
If you are getting a “Possible unhandled promise rejection” warning in your React Native app, it means that a promise was rejected, but the rejection was not handled. Promises in JavaScript are used to handle asynchronous operations, and they can either be resolved or rejected.
axios.post(URL+'/checkData',
{
usernameCheckAXIOS : username,
passwordCheckAXIOS : password,
})
.then((response)=>{
//... your code
})
.chatch(error => console.log(error)) // <-- add this line
The HTTP 404 Not Found response status code indicates that the server cannot find the requested resource
so verify your URL, should be invalid because it cannot be found.
[Axios error: Request failed with statis code 404] is an error URL not found.
Are you sure that the url URL+'/checkData' is valid ?

How can I fix an Axios interceptor causing property 'status' of undefined error

I have a selection to set permissions for elements to global or private. I'm using the Axios interceptor request to handle looking for the permissions field to have data and, if it does, stringify it. The problem is, it causes me to get a "TypeError: Cannot read property 'status' of undefined" when I attempt to reload the program at all. The only "fix" right now is to log out, remove the interceptor, log in, read it, and then run the check again.
Because of this, I can't even get to the home dashboard of the software. If I clear my cookies, I can go back to the login screen, but no further than that after attempting to log in.
Is there something I'm missing for it? below is the interceptor code. If more information or context is needed, please let me know.
export default {
install: (Vue) => {
Vue.$eventBus = new Vue();
Vue.axios.interceptors.response.use(response => {
return response.data;
}, async error => {
if (error.response.status === 401 && error.config.url != '/api/authentication/login') {
var config = await Vue.$configService.find();
window.location = config.accountPortalUrl;
return
}
console.log(error);
Vue.$eventBus.$emit('notifyUser', 'Uh oh, something went wrong!');
return Promise.reject(error);
});
Vue.axios.interceptors.request.use(
config => {
// check request method -> use post if many params
if (config.data.permissions) {
config.data.permissions = JSON.stringify(config.data.permissions);
}
console.log(config);
return config;
}
);
}
};
Looks like your service API is not responding, this might happen if the user is not authenticated . Your error is at line where you check (error.response.status). Its only possible to get an undefined response when the request was interrupted before response. Most probably if you check your browser network pannel you will see that the preflight check for this request causes a 401 network error. Hence because the preflight failed your actual response comes as undefined. You should sanity check first if your server responded with a response or not and then access the response status.
Something like this might help
if (error.response) {
// Request was made and the server responded successfully
// You can now de-structure the response object to get the status
console.log(error.response.status);
} else if (error.request) {
// request was made but not responded by server
console.log(error.request);
}
So, the answer ultimately was something extremely simple.
if (config.data.permissions)
needed to be
if (config.data && config.data.permissions)

How to get the data associated with the error response back?

I am making a request from the front-end to a route in my backend that is validating the token associated with a user, which would send an error response back to the front-end if the token has expired. I am sending some json with it but upon doing console.log of the error message in the catch block, the json sent along the error response is not shown.
Sending the error response like this
res.status(401).json({
message: 'User session has expired'
})
But the response that I am getting in the catch block in the front-end has no sign of the json sent with the error.
POST http://localhost:3001/check-validation 401 (Unauthorized)
Error: Request failed with status code 401
at createError (createError.js:17)
at settle (settle.js:19)
at XMLHttpRequest.handleLoad (xhr.js:78)
I don't understand why the json sent along the error response is not shown and how to get it?
Upon doing console.log of the error only the stacktrace of the error is shown and not the data associated with it. The data sent with it can be procured and depends on how the request has been made or by what library it has been made. If the request is made by axios then the following can be done:
axios.post('/formulas/create', {
name: "",
parts: ""
})
.then(response => {
console.log(response)
})
.catch(error => {
console.log(error.response.data.message)
});
Here, in axios the details of the error would be wrapped up in error.response. Whereas, if the request was made by the fetch API then something following can resolve the problem:
fetch('/401').then(function(response) {
if (response.status === 401) {
return response.json()
}
}).then(function(object) {
console.log(object.message)
})
P.S I was searching a lot regarding this problem but didn't get an answer on SO, neither got any article or docs regarding it, even the official Express docs on error handling were not helpful. At last, I understood that the problem lies with the library that is being used to make the request. That's why answering my own question to mark the presence of this question on SO. A detailed discussion can be found here related to axios and here related to fetch api

Loopback error - value is not an object

I am using loopback in backend. I am getting this error
Unhandled error for request POST /api/meetups/auth: Error: Value is not an object.
at errorNotAnObject (/Users/ankursharma/Documents/projects/meetupz/node_modules/strong-remoting/lib/types/object.js:80:13)
at Object.validate (/Users/ankursharma/Documents/projects/meetupz/node_modules/strong-remoting/lib/types/object.js:51:14)
at Object.fromTypedValue (/Users/ankursharma/Documents/projects/meetupz/node_modules/strong-remoting/lib/types/object.js:14:22)
at Object.fromSloppyValue (/Users/ankursharma/Documents/projects/meetupz/node_modules/strong-remoting/lib/types/object.js:41:17)
at HttpContext.buildArgs (/Users/ankursharma/Documents/projects/meetupz/node_modules/strong-remoting/lib/http-context.js:193:22)
at new HttpContext (/Users/ankursharma/Documents/projects/meetupz/node_modules/strong-remoting/lib/http-context.js:59:20)
at restStaticMethodHandler (/Users/ankursharma/Documents/projects/meetupz/node_modules/strong-remoting/lib/rest-adapter.js:457:15)
at Layer.handle [as handle_request] (/Users/ankursharma/Documents/projects/meetupz/node_modules/express/lib/router/layer.js:95:5)
at next (/Users/ankursharma/Documents/projects/meetupz/node_modules/express/lib/router/route.js:137:13)
at Route.dispatch (/Users/ankursharma/Documents/projects/meetupz/node_modules/express/lib/router/route.js:112:3)
at Layer.handle [as handle_request] (/Users/ankursharma/Documents/projects/meetupz/node_modules/express/lib/router/layer.js:95:5)
at /Users/ankursharma/Documents/projects/meetupz/node_modules/express/lib/router/index.js:281:22
at Function.process_params (/Users/ankursharma/Documents/projects/meetupz/node_modules/express/lib/router/index.js:335:12)
at next (/Users/ankursharma/Documents/projects/meetupz/node_modules/express/lib/router/index.js:275:10)
at Function.handle
(/Users/ankursharma/Documents/projects/meetupz/node_modules/express/lib/router/index.js:174:3)
at router (/Users/ankursharma/Documents/projects/meetupz/node_modules/express/lib/router/index.js:47:12)
I have already searched stackoverflow, but I didnt find answer. Basically, i was trying to use body-parser . I went through one of the stackoverflow thread and implemented its solution. I was able to use body-parser successfully. So, that error has been solved. But, now this error is giving me tough time.
server.js file
'use strict';
var loopback = require('loopback');
var boot = require('loopback-boot');
var bodyParser = require('body-parser');
var multer = require('multer');
var app = module.exports = loopback();
//code for body parsing
app.use(bodyParser.json()); // for parsing application/json
app.use(bodyParser.urlencoded({ extended: true })); // for parsing application/x-www-form-urlencoded
//app.use(multer()); // for parsing multipart/form-data
//code for body parsing ends
app.start = function() {
// start the web server
return app.listen(function() {
app.emit('started');
var baseUrl = app.get('url').replace(/\/$/, '');
console.log('Web server listening at: %s', baseUrl);
if (app.get('loopback-component-explorer')) {
var explorerPath = app.get('loopback-component-explorer').mountPath;
console.log('Browse your REST API at %s%s', baseUrl, explorerPath);
}
});
};
// Bootstrap the application, configure models, datasources and middleware.
// Sub-apps like REST API are mounted via boot scripts.
boot(app, __dirname, function(err) {
if (err) throw err;
// start the server if `$ node server.js`
if (require.main === module)
app.start();
});
In middleware.json, I have updated parse property as well
"parse": {"body-parser#json": {},
"body-parser#urlencoded": {"params": { "extended": true }}},
For some reason, that error has gone. Not sure, may be it will come again. But now, this is the error, I am seeing
Unhandled error for request POST /api/meetups/auth: TypeError: cb is not a function
at Function.Meetups.auth (/Users/ankursharma/Documents/projects/meetupz/common/models/meetups.js:117:3)
at SharedMethod.invoke (/Users/ankursharma/Documents/projects/meetupz/node_modules/strong-remoting/lib/shared-method.js:270:25)
at HttpContext.invoke (/Users/ankursharma/Documents/projects/meetupz/node_modules/strong-remoting/lib/http-context.js:297:12)
at phaseInvoke (/Users/ankursharma/Documents/projects/meetupz/node_modules/strong-remoting/lib/remote-objects.js:677:9)
at runHandler (/Users/ankursharma/Documents/projects/meetupz/node_modules/strong-remoting/node_modules/loopback-phase/lib/phase.js:135:5)
at iterate (/Users/ankursharma/Documents/projects/meetupz/node_modules/strong-remoting/node_modules/loopback-phase/node_modules/async/lib/async.js:146:13)
at Object.async.eachSeries (/Users/ankursharma/Documents/projects/meetupz/node_modules/strong-remoting/node_modules/loopback-phase/node_modules/async/lib/async.js:162:9)
at runHandlers (/Users/ankursharma/Documents/projects/meetupz/node_modules/strong-remoting/node_modules/loopback-phase/lib/phase.js:144:13)
at iterate (/Users/ankursharma/Documents/projects/meetupz/node_modules/strong-remoting/node_modules/loopback-phase/node_modules/async/lib/async.js:146:13)
at /Users/ankursharma/Documents/projects/meetupz/node_modules/strong-remoting/node_modules/loopback-phase/node_modules/async/lib/async.js:157:25
at /Users/ankursharma/Documents/projects/meetupz/node_modules/strong-remoting/node_modules/loopback-phase/node_modules/async/lib/async.js:154:25
at execStack (/Users/ankursharma/Documents/projects/meetupz/node_modules/strong-remoting/lib/remote-objects.js:522:7)
at RemoteObjects.execHooks (/Users/ankursharma/Documents/projects/meetupz/node_modules/strong-remoting/lib/remote-objects.js:526:10)
at phaseBeforeInvoke (/Users/ankursharma/Documents/projects/meetupz/node_modules/strong-remoting/lib/remote-objects.js:673:10)
at runHandler (/Users/ankursharma/Documents/projects/meetupz/node_modules/strong-remoting/node_modules/loopback-phase/lib/phase.js:135:5)
at iterate (/Users/ankursharma/Documents/projects/meetupz/node_modules/strong-remoting/node_modules/loopback-phase/node_modules/async/lib/async.js:146:13)
check if your filters or your URL has black spaces i.e. %20, or anything wrong with the filter or url.
Loopback 3 makes a difference between array and object. You have to check your data type. See https://github.com/strongloop/strong-remoting/issues/360 for more information.
I was facing the same error but in my case it was due to a model property data length.The property was type object and a small dataLength which caused faulty record in my sql Model table.I have to Manually delete those faulty records and increase the dataLength of that property too.
Restart the app

Error Handling ExpressJS and MongoDB

What is the suggested way of error handling in ExpressJS and Mongoose.
app.get('/', function(req, res) {
Subjects.find({}, function(err, subjects) {
if (err) {
return res.json(err);
}
res.render('list', {subjects: subjects});
});
});
I just returned the error in json. Any suggestions? Thanks
It depends on what that error is, but I would usually redirect via res.redirect to an 'Error' url, with details of the error.
You could test for the details of the error, and re-run a query (dependent on what the error is of course) but usually if the callback is throwing an error, it's terminal, so log it, redirect, and inform the user in a nice way.
(Or of course, return JSON and handle your response client side, with no redirect)
EDIT
As per comment from Paul -
I didn't mean to return the exact details to the user about the error.
Simply "Database error" or something like that would be more appropriate, depending on what the error was.