Intercept api errors - react-admin

I'm using react-admin with standard crud options, I want to react to the RA/CRUD_GET_LIST_FAILURE (and all others in the future) to logout the user if the error is a 401 (like when the token timed out)
How am I supposed to do this ?
On custom requests I have my own sagas which handle this in the catch part and correctly do the job.
If I try to intercept the RA/CRUD_GET_LIST_FAILURE like this :
function * loadingErrorRA (action) {
var e = action.payload;
console.error('loadingError',action);
if(action.error === "Unauthorized"){
//I can't find a better way because I don't have access to the fetch response object in here
yield put(userLogout());
yield put(showNotification('Disconnected','warning'));
} else {
yield put(showNotification('Error '+action.error,'warning'));
}
}
function * errorLoadingSaga() {
yield takeLatest('RA/CRUD_GET_LIST_FAILURE', loadingErrorRA);
}
I have a blank screen and an error pops :
ListController.js:417 Uncaught TypeError: Cannot read property 'list' of undefined
at Function.mapStateToProps [as mapToProps] (ListController.js:417)
at mapToPropsProxy (wrapMapToProps.js:43)
at handleNewPropsAndNewState (selectorFactory.js:34)
at handleSubsequentCalls (selectorFactory.js:67)
at pureFinalPropsSelector (selectorFactory.js:74)
at Object.runComponentSelector [as run] (connectAdvanced.js:26)
at Connect.componentWillReceiveProps (connectAdvanced.js:150)
at callComponentWillReceiveProps (react-dom.development.js:11527)
....
index.js:2178 The above error occurred in the <Connect(TranslatedComponent(undefined))> component:
in Connect(TranslatedComponent(undefined)) (created by List)
in List (created by WithStyles(List))
in WithStyles(List) (at SalesByOrganismList.js:40)
in div (at SalesByOrganismList.js:39)
in SalesByOrganismList (created by WithPermissions)
in WithPermissions (created by Connect(WithPermissions))
in Connect(WithPermissions) (created by getContext(Connect(WithPermissions)))
...
And then saga catch it with :
index.js:2178 uncaught at loadingErrorRA TypeError: Cannot read property 'list' of undefined
at Function.mapStateToProps [as mapToProps]
...
Thanks for the help

https://marmelab.com/react-admin/DataProviders.html#error-format
When the API backend returns an error, the Data Provider should throw an Error object. This object should contain a status property with the HTTP response code (404, 500, etc.). React-admin inspects this error code, and uses it for authentication (in case of 401 or 403 errors). Besides, react-admin displays the error message on screen in a temporary notification.
And https://marmelab.com/react-admin/Authentication.html#catching-authentication-errors-on-the-api
Each time the API returns an error, the authProvider is called with the AUTH_ERROR type. Once again, it’s up to you to decide which HTTP status codes should let the user continue (by returning a resolved promise) or log them out (by returning a rejected promise).

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 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

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

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);

Get PDF files from Worklight Server to the client

Based on the following reference:- Worklight Adapter getting pdf file from rest service, i got the PDF file from tomcat server through the worklight adapter. The server side code is:-
var input = {
method : 'get',
returnedContentType : 'plain',
path : '/PDF/example-abstract.pdf'
};
return WL.Server.invokeHttp(input);
When i invoke the invoke the procedure i am able to successfully retrieve the result. When i invoke the same procedure from client side like below:-
var invocationData = {
adapter: 'PdfReader',
procedure: 'readPDF',
parameters: []
};
I am unable to receive the response in the success handler. In logcat it showing the following error:-
07-03 13:07:05.330: E/pdf(4214): [http://Path-to-pdf:10080/pdf/apps/services/api/pdf/android/query] exception. SyntaxError: Unexpected token ILLEGAL
07-03 13:07:05.377: D/dalvikvm(4214): GC_FOR_ALLOC freed 347K, 10% free 8082K/8967K, paused 19ms
07-03 13:07:05.424: D/dalvikvm(4214): GC_CONCURRENT freed 155K, 7% free 8390K/8967K, paused 2ms+3ms
07-03 13:07:05.424: D/pdf(4214): response [http://Path-to-pdf:10080/pdf/apps/services/api/pdf/android/query] success: {"responseID":"2","statusCode":200,"text":"%PDF-1.4\n%????\n3 0 obj <<\n\/Length 2445 \n\/Filter \/FlateDecode\n>>\nstream\nx?X[??\n~?_?#?YQ?O?dw??M??3?4'\u000f0 \\Shorted
07-03 13:07:05.424: W/PluginManager(4214): THREAD WARNING: exec() call to Logger.DEBUG blocked the main thread for 45ms. Plugin should use CordovaInterface.getThreadPool().
07-03 13:07:05.455: E/pdf(4214): [http://Path-to-pdf:10080/pdf/apps/services/api/pdf/android/query] exception. TypeError: Cannot read property 'isSuccessful' of undefined
07-03 13:07:05.455: D/CordovaLog(4214): file:///data/data/com.pdf/files/www/default/worklight/worklight.js: Line 3320 : Uncaught SyntaxError: Unexpected token ILLEGAL
07-03 13:07:05.455: E/Web Console(4214): Uncaught SyntaxError: Unexpected token ILLEGAL at file:///data/data/com.pdf/files/www/default/worklight/worklight.js:3320
07-03 13:07:05.463: D/CordovaLog(4214): file:///data/data/com.pdf/files/www/default/worklight/worklight.js: Line 3320 : Uncaught TypeError: Cannot read property 'isSuccessful' of undefined
07-03 13:07:05.471: E/Web Console(4214): Uncaught TypeError: Cannot read property 'isSuccessful' of undefined at file:///data/data/com.pdf/files/www/default/worklight/worklight.js:3320
I need to know, how to make it reachable in the successHandler. Thanks in advance.
The problem is with parsing the JSON data, based on the following answer, I have converted the Json data to string using JSON.stringify(), so that the string can successfully reach the successHandler inside the handler i am using JSON.parse() to convert the string to JSON for use.

Dojo JsonRestStore, fetch, onError callback and HTTP status code?

I would like to know how to obtain the HTTP status code returned after a fetch() operation is performed. I have specified the onComplete and onError callbacks to the fetch() call.
The onError is called in case of an error, but I am unable to obtain the HTTP status code from the parameter passed to onError (it's just the request, not the response).
With XhrGet I was able to get the status code from the ioArgs, and it seems that the JsonRestStore does not handle it that way.
I'm using Dojo 1.5.1 (and I really cannot upgrade yet to 1.6)
The error handler is given two arguments. The second argument (which I called config) has a property called xhr which contains... status and status text.
dojo.xhrGet({
url:'/bogusPath/',
error:function(error, config){
console.log('XHR-ErrorHandle',arguments);
console.log('XHR-ErrorHandle-status:',config.xhr.status);
console.log('XHR-ErrorHandle-statusText:',config.xhr.statusText);
}
})
Returns:
XHR-ErrorHandle [Error, Object]
XHR-ErrorHandle-status: 404
XHR-ErrorHandle-statusText: Not Found