The UI should have a global error handler that shows a popup message whenever an error is received through the API. I'm trying but I'm not getting, I did not find any example too. This should be done Marionette.js. Please help
I got a json file:
{
"errorcodes": [{
"message": "Invalid Email/Password Combination",
"reason": "com.catt.exceptions.catttCustomerPreferencesException: Invalid Email/Password Combination\r\n\tat com.catt.v1.controller.CustomersController.customerLogin(CustomersController.java:303)\r\n\tat sun.reflect.GeneratedMethodAccessor1008.invoke(Unknown Source)\r\n\tat sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)\r\n\tat java.lang.reflect.Method.invoke(Method.java:606)\r\n\tat org.springframework.web.method.support.InvocableHandlerMethod.invoke(InvocableHandlerM...",
"type": "tCustomerPreferencesError"
}]
}
You can use $.ajaxError to listen for any error happening in $.ajax.
From there, you can make make a Marionnette Application (for example), handle the error, and display an alert
var App = new Marionette.Application();
App.vent.on('error', function(event, jqxhr){
alert(jqxhr.responseText);
});
$(document).ajaxError(function(event, jqxhr, settings, thrownError){
App.vent.trigger('error', event, jqxhr, settings, thrownError);
});
Fiddle Here : http://jsfiddle.net/8ff4n9ut/
Related
I'm starting to learn Solidity and how to interact with smart contracts within a Dapp, and I would like to know how can I log/handle errors from the contract in my Dapp.
For example, in the Dapp I have a button, when you click it, it runs a function in the contract, I have a require() there with a specific message: "Wait 15m", basically, the user can only click this button once every 15 minutes.
The button interaction is fired in a try/catch, if the user already clicked the button, so the next time will catch the error. My problem is the error that I'm getting in the console (to debug), it is like:
Error: transaction failed (transactionHash="0xe95c970115f5fe55202d04c2e0cd83c2ff67d3653f5397d7739764d685249da6", transaction={"hash":"0xe95c970115f5fe55202d04c2e0cd83c2ff67d3653f5397d7739764d685249da6","type":2,"accessList":null,"blockHash":null,"blockNumber":null,"transactionIndex":null,"confirmations":0,"from":"0xc6682cDC60a1e4603D051e48A2970E4859C62521","gasPrice":{"type":"BigNumber","hex":"0x59682f11"},"maxPriorityFeePerGas":{"type":"BigNumber","hex":"0x59682f00"}......
It is just a string with this bunch of code, without the error message specified in the require() which is the thing that is firing the error. This is the transaction in Rinkeby.
So, I imagine, in the future, I could have many functions in my contract with many require() with different messages. How can I handle these errors and show valuable information to the user in the UI? Is there any function that could help to get the proper messages?
I'm using:
Ethers - React
Thanks in advance for any help!
To extract error message from revert and require in the contract, please use provider.call to retrieve the error data. The following code works well with alchemy provider and goerli net. (ethers.js version 5.6.8)
const alchemyProvider = new ethers.providers.AlchemyProvider(
(network = "goerli"),
API_KEY
)
const tx = await alchemyProvider.getTransaction("0x5479d838aa66169470a61a8347727b75264e1d5d68d6749e5bd59b44d525dc21");
const code = await alchemyProvider.call(
{
to: tx.to,
from: tx.from,
nonce: tx.nonce,
gasLimit: tx.gasLimit,
gasPrice: tx.gasPrice,
data: tx.data,
value: tx.value,
chainId: tx.chainId,
type: tx.type ?? undefined,
accessList: tx.accessList,
},
tx.blockNumber,
)
const decodedError = SimpleAuction.interface.parseError(code)
console.log(decodedError)
console.log(`Transaction failed: ${decodedError.name}`)
The transaction info in etherscan which error encountered during contract revert execution. So the "code" is detailed and raw error info, and can be parsed and fromatted by interface. The output of error showed in the following.
ErrorDescription {
args: [
BigNumber { _hex: '0x01', _isBigNumber: true },
highestBid: BigNumber { _hex: '0x01', _isBigNumber: true }
],
errorFragment: {
type: 'error',
name: 'BidNotHighEnough',
inputs: [ [ParamType] ],
_isFragment: true,
constructor: [Function: ErrorFragment] {
from: [Function (anonymous)],
fromObject: [Function (anonymous)],
fromString: [Function (anonymous)],
isErrorFragment: [Function (anonymous)]
},
format: [Function (anonymous)]
},
name: 'BidNotHighEnough',
signature: 'BidNotHighEnough(uint256)',
sighash: '0x4e12c1bb'
}
The "BidNotHighEnough" is an reverted error defined in the contract. So that all the detailed erro info.
I'm currently trying to POST data to my aws lambda functions triggered by aws api-gateway using the aws-amplify react lib.
Here is the code :
API.post("snippets","snippets/", {
body: data,
}).then(response => response).catch(console.log(err))
In the main case, everything is OK.
But my lambda function is design to validate the input data and return a status code 400 with a returned payload looking like that :
{
"errors": [
{
"field": "title",
"message": "This field is required"
}
]
}
I would like to catch those errors in order to display them in the frontend but aws-amplify seems to have an undocumented behavior.
By default, status code 400 returned are throw with a default error message :
Error: Request failed with status code 400
at createError (createError.js:16)
at settle (settle.js:18)
at XMLHttpRequest.handleLoad (xhr.js:77)
Is there a way to get the returned payload instead of this magical error?
It turns out that under the hood, aws-amplifyuse Axios to make http calls.
When using Axios, you have to console.log(error.response): https://github.com/axios/axios/issues/960
Here is the fix I've made :
API.post("snippets","snippets/", {
body: data,
}).then(response => response).catch(error => console.log(error.response.data))
A Pull Request on the aws-amplify documentation is open : https://github.com/aws/aws-amplify/pull/633
I also faced the similar issues, It showed the default error message "Request failed with status code 400", instead of the message that is returned from API.
I logged the Error object and it did not show the response attribute in it. But we do have response attribute. I tried logging the Error.response and it did contain the response sent from the API.
Just figured out this by going through the 'Cancel API requests' Amplify docs.
From what I can see this is the contents of the error object returned by the API call:
Heres what I am doing to just print out the error, obviously you would do a lot more here but its a good start.
async uploadUser(state, payload) {
const promise = API.graphql({
query: createUser,
variables: { input: payload },
});
try {
await promise;
} catch (error) {
// Print out the actual error given back to us.
console.log(error.errors[0].message);
// If the error is because the request was cancelled we can confirm here.
if (API.isCancel(error)) {
// handle user cancellation logic.
console.log(error.message);
}
}
Hope that helps 😃
I am trying to create a Webhook (aka Subscription) for users who are created, updated, or deleted in Office 365.
With the "changeType": "updated" it works fine but with "changeType": "created" it returns an error:
This is the request:
{
"changeType": "created,updated,deleted",
"notificationUrl": "https://ourLink",
"resource": "users",
"expirationDateTime": "2017-12-16T14:49:57Z",
"clientState": "pe1g9gqiVsE6KnHTUuK9Tts3o660KOAw9YnavVfKhr22I7FlqC0tfMhpayxrqFP4orFPOjK0rppYtDicvxZosbvOEEgfy3YYoM3FGDwLQiW4MAdSCTdQkffuChjmB"
}
Error:
{
"header": 400,
"body": {
"error": {
"code": "InvalidRequest",
"message": "Invalid 'changeType' attribute: 'created'.",
"innerError": {
"request-id": "74454900-d3df-4962-b58e-cfd7ec7454bc",
"date": "2017-12-13T16:49:59"
}
}
}
}
Creating a subscription to a user resource is only available in the Beta API
but according to the documentation, it should work.
Based on the error message and that the User Webhook sample application only handles updated and deleted, this should be the expected behavior.
I'm also unable to find where in the documentation it states that a user resource accepts subscriptions for created. If you could provide a link I will make sure the documentation gets updated.
With a custom remote validator, how are you supposed to get rid of the error messages?
Using data-parsley-remote-validator='mycustom' on the field will give you an error in the console 'undefined async validator' unless the validator is added on DOM ready i.e not inside another function. However, if it is added on DOM ready, then parsley automatically calls it, which shouldn't happen until submit/change or whatever else you have set.
I can do something like this, but it kind of defeats the object of having parsley call the validator on change:
$('#signUpForm').on('submit', function() {
//add the attribute here to avoid the initial error message
$('#exampleInputEmail1').attr('data-parsley-remote-validator', 'validateEmail');
//then add the custom validator
$('#exampleInputEmail1').parsley()
.addAsyncValidator('validateEmail', function (xhr) {
if(xhr.status == '200') {
return 200;
}
// return the error message if email is taken
else if(xhr.status == '404') {
response = '<ul class="errorlist"><li>That email has already been taken, please try another</li></ul>'
$('#errorResponse').html(response);
}
}, '/api/v1/email/available', { "type": "POST", "dataType": "json", "data": data }
);
});
For those who came here for custom remote validator error message in Parsley.js,
You can add data-parsley-remote-message to the element,
<input type="text" data-parsley-remote-validator="my_remote_validator" data-parsley-remote-message="Custom error message only for remote validation on this element" >
Tested with Parsley.js - Version 2.3.11
Your asynch validator is not supposed to set an error message itself, it should simply return if the value validates or not. The error messages are added with a different API and/or specified as data attributes, check the doc.
I am trying to create a calendar using Google Calendar API v3 if it does not already exist. My implementation successfully retrieves all my calendars and events and can change calendars, but I am struggling with adding a new calendar. This is what I do in order to try to add a new calendar for the user:
...
var calendarService = new CalendarService(_authenticator);
var calendarId = "com.somedomain.somename.1234"; // Some random ID
try {
calendarManager.GetCalendar(calendarId); // No calandar found
} catch(GoogleCalandarServiceProxyException e){
// Ok, so far so good, calendar not found (that is correct) and I am here
var someCalendar = new Google.Apis.Calendar.v3.Data.CalendarListEntry {
Summary = "Some summary!",
Description = "A calendar descr.",
AccessRole = "writer",
BackgroundColor = "#E7323C",
Id = calendarId
};
calendarService.CalendarList.Insert(someCalendar).Fetch(); // Fetch to execute
}
Request generated:
insert # https://www.googleapis.com/calendar/v3/users/me/calendarList?alt=json&prettyPrint=true
RequestError:
Google.Apis.Request.RequestErrorNotFound[404]Errors [Message[Not Found]Location[-] Reason[notFound] Domain[global]]]
Weird thing is that doing a GET at https://www.googleapis.com/calendar/v3/users/me/calendarList?alt=json&prettyPrint=true does not return something, so it should be there.
I hope that there is some awesome guy/girl out there which knows what to do! I'm completely stuck.
Update
Seems like I am receiving the same 404 error on CalendarList Google Api Explorer also:
Url:
https://developers.google.com/google-apps/calendar/v3/reference/calendarList/insert
Request:
POST https://www.googleapis.com/calendar/v3/users/me/calendarList?key={YOUR_API_KEY}
Content-Type: application/json
Authorization: Bearer ya29.AHES6ZQTj-D6uIMOWr_AoFYVvfefsEGcVvLvvMf4aKhgrdvQE25aVw
X-JavaScript-User-Agent: Google APIs Explorer
{
"id": "hastalavista"
}
Response:
404 Not Found
- Show headers - { "error": { "errors": [ {
"domain": "global",
"reason": "notFound",
"message": "Not Found" } ], "code": 404, "message": "Not Found" } }
Does anyone know whether Google have changed the URL for this resource? And if yes, how I change the Google Calendar Api v3 to use the updated url ...?
Okey, my bad:
You can't create a calendar with your own identifier, the purpose of CalendarListEntry.Insert() is to insert a created Calendar into the list of calendars
So to create a new calendar one has to:
Insert a new Calendar: https://developers.google.com/google-apps/calendar/v3/reference/calendars/insert
(DO NOT add id as paramater, this will be automatically created)
Insert the ID of the calendar created in step 1 and insert it into the calendarList: https://developers.google.com/google-apps/calendar/v3/reference/calendarList/insert
I'm still totally confused as to Google's distinction between a Calendar and a CalendarList since the data seems to overlap. Why is a calendar considered a "secondary" calendar.
The next code dit the trick for me, The mentioned reference is Java not .Net and, as usual ther e are some anoying differences...
private bool createCalendar()
{
// use Google.Apis.Calendar
Calendar calendar = new Calendar();
calendar.Summary = "MyNewCalendar";
calendar.Description = "Your new Calendar";
calendar.Location = "Aadorp";
calendar.TimeZone = "Europe/Amsterdam";
try
{
// Not inserting in CalendarList but in Calendar!
calendarService.Calendars.Insert(calendar).Execute();
}
catch (Exception exception)
{
MessageBox.Show(exception.Message);
return false;
}
return true;
}