I'm getting an exception when using the Java Google Calendar API that I can't make heads or tails of. What I'm doing is creating a connector to Google Calendar that inserts events. Some of these events are repeating, and some of those have exceptions to the repeat pattern. I've been very successful in creating events and repeating events, but am having these problems when trying to make exceptions.
The code I'm using is:
CalendarEventEntry gglAppt = new CalendarEventEntry();
OriginalEvent originallink = new OriginalEvent();
originallink.setOriginalId(repeatingEvent.getIcalUID());
When originalWhen = new When();
originalWhen.setStartTime(DateTime.parseDate("2011-05-01"));
originallink.setOriginalStartTime(originalWhen);
When exceptionWhen = new When();
exceptionWhen.setStartTime(DateTime.parseDate("2011-05-10"));
gglAppt.setOriginalEvent(originallink);
gglAppt.setStatus(EventStatus.CANCELED);
gglAppt.addTime(exceptionWhen);
try {
//I can vouch for this line, it works elsewhere in the code.
//CalendarServiceManager is a custom class if you didn't guess ;-)
CalendarServiceManager.getInstance().addNewEvent(gglAppt, http://www.google.com/calendar/feeds/default/calendars/testemail%40gmail.com);
} catch (IOException e) {
e.printStackTrace();
} catch (ServiceException e) {
e.printStackTrace();
}
The exception is:
com.google.gdata.util.InvalidEntryException: Bad Request
Element must contain value for attribute id
at com.google.gdata.client.http.HttpGDataRequest.handleErrorResponse(HttpGDataRequest.java:594)
at com.google.gdata.client.http.GoogleGDataRequest.handleErrorResponse(GoogleGDataRequest.java:563)
at com.google.gdata.client.http.HttpGDataRequest.checkResponse(HttpGDataRequest.java:552)
at com.google.gdata.client.http.HttpGDataRequest.execute(HttpGDataRequest.java:530)
at com.google.gdata.client.http.GoogleGDataRequest.execute(GoogleGDataRequest.java:535)
at com.google.gdata.client.Service.insert(Service.java:1409)
at com.google.gdata.client.GoogleService.insert(GoogleService.java:599)
at com.testapp.google.CalendarServiceManager.addNewEvent(CalendarServiceManager.java:138)
at com.testapp.google.GoogleAdapter.dealWithExceptions(GoogleAdapter.java:581)
...etc
My understanding from what I've seen around the interwebs is that an attribute ID is something you set for Google objects for you to keep track of them. I wouldn't know where to set an attribute ID, and I'm puzzled as to why I haven't had to set an attribute ID for any of the other events I've submitted.
What is this exception that's being thrown? What does it mean and what do I do about it?
Any help would be greatly appreciated as always.
Found the answer to my question here:
http://code.google.com/apis/calendar/community/forum.html?place=topic%2Fgoogle-calendar-help-dataapi%2FvD6xahZq8ms%2Fdiscussion
Turns out repeatingEvent didn't have an id yet. I had just created it and sent it off to the server, but hadn't updated the local object with the one returned from the server; the one with an id.
Related
I am not able to understand why Java doesn't allow to change exception message of an exception of type Exception (or its superclass Throwable) once it has been created. It allows to change the stackTrace using setStackTrace but not the message.
The use case I have seems genuine to me and would appreciate some alternative.
Use case
I have a controller service X that calls let's say 10 other dependent services. To make debugging easy, if a dependent service throws some exception we want to surface some identifiers from service X to its upstream to identify the failed request easily. For this we have requestId which we create and set for each dependency.
Now to avoid duplication across all dependent services and simplify code, we can create a common interceptor that allows us to do some work before and after each call. Something like -
// do some work
requestId = getRequestId(); // create or somehow get requestId
dependentService.setRequestId(requestId);
try {
dependentService.call();
}
catch (Exception e) {
e.setMessage(e.getMessage() + ... + requestId);
throw e;
}
//do some work
But Java doesn't allow us to set message. At the same time, we want to preserve the exception and its type (which could be any of the custom types defined by dependent services), so I don't want to do something like throw new Exception(e.getMessage() + ...)
It's not really what it's meant for, but you could attach another exception with addSuppressed:
} catch (Exception e) {
e.addSuppressed(new ExtraInfoException(...));
throw e;
}
where ... contains the extra info you want to include.
The advantage of this over adding to the exception message is that you can define your ExtraInfoException so that it has the info you want in fields, rather than having to parse it back out of the exception message.
With that said, a more idiomatic way to attach more exception info it would be:
} catch (Exception e) {
throw new ExtraInfoException(e, ...);
}
which has exactly the same advantage of allowing you to return structured information, with the additional advantage that you can catch ExtraInfoException directly, rather than catching Exception and then hunting for the extra info reflectively.
Why doesn't Java have setMessage in Exception/Throwable classes?
The answer to your question is that they (the library designers) did not think that changing a message on an exception was a useful thing to do.
To a large degree1, the designers have taken the view that they shouldn't design the APIs to directly support all possible use-cases ... including the obscure ones that almost nobody will encounter. Like your one2.
And in your case, there are other ways to achieve what you are trying to do; see the other answers.
I did a quick search of the Java bugs database to see if someone else had put in an RFE to request a setMessage method for Throwable or Exception. I couldn't find anything. If your requirement was even slightly common, there would probably be an RFE with an explanation of why it was declined.
1 - Obviously, there are exceptions to this, but that is beside the point.
2 - Obviously you would disagree that your use-case is obscure, but that that is also beside the point. The question is why they haven't implemented this, not whether they were wrong. (Asking / debating whether they were wrong is off-topic, because it is a matter of opinion.)
Resetting a message it's some kind of rewriting the history. You have a catch block when you catch exception and handle them. If you need to throw an exception during the handling, it's a different problem and an exception should be different.
} catch (SomeException e) {
// here we have SomeException and we want to handle it.
// if we can't we throw a new one, because we have a problem with handling.
// if the handling problem cause is SomeException we put it at the cause.
throw new AnotherException("with some message", e);
}
And in the stacks trace we will see that we have AnotherException because of SomeException which gives us information about the root of problem.
Just simply throw new instance like this:
try {
...
} catch(Exception ex) {
throw new Exception ("new message", ex);
}
I am developing an application which uses MongoDB, and one of my fields must be unique. This field is calculated by the application based on another value in the DB. If I am running multiple instances of the application, however, I can imagine the applications calculating the same value.
In this case, I would like to catch the exception, recalculate the value, and try again. Unfortunately, the exception raised seems to be a simple MongoWriteException. It seems to me that the only way I will know that it is due to the duplicate key issue is based on the exception message, but parsing and making use of the message really doesn't feel right. Are there any other options?
You can check the ErrorCategory of the error inside the MongoWriteException and confirm it was due to a duplicate key using getCategory():
catch(MongoWriteException ex) {
if(ex.getError().getCategory() == ErrorCategory.DUPLICATE_KEY) {
//handle duplicate key error
} else {
//do something else...
}
}
I am currently trying to create an automation framework using Java and Selenium.
I want to create a line of code which essentially can read any input and make it a line of runnable code. For example, in an external file, a user could post 'id' into a field, that field will then be read by my program and execute the line. driver.findElement(By.id(.......)
Currently I'm using a bunch of if statements to do this for each identifier e.g. id, cssSelector, Xpath etc etc but then I'll need to do the same for the actions used by the program .click, .sendKeys etc so the program will just keep expanding and look overall very messy.
Is there a solution that would allow me to do this in a nicer way or am I stuck with my original approach?
Reflection is probably the most direct way to solve this. It essentially allows classes and methods to be looked up by their string names.
Here's a fag-packet example of how you might approach this using the snippet you provided, but I suggest you read some documentation before diving in.
Element findElementReflectively(Driver driver, String elementType, String thingToSearchFor) {
try {
Method m = By.class.getMethod(elementType, String.class);
if(!Modifier.isStatic(m.getModifiers())) {
throw new NoSuchMethodException("'By' method is not static.");
}
return driver.findElement(m.invoke(null, thingToSearchFor));
} catch (IllegalAccessException | NoSuchMethodException e) {
throw new IllegalArgumentException("Unknown element type: " + elementType, e);
} catch (InvocationTargetException e) {
throw new RuntimeException("Failed to find requested element.", e.getCause());
}
}
It depends on what you actually want to do.
Reading an id from a file and then execute code can be achieved through config file with this : Properties
Or if you want to execute full input code just search a little bit more
How to execute console or GUI input as if it was actual Java code?
what I want to do is get all the events in a given google calendar for a given date.
Now we can get the event listing pretty easily using the following code
public Events getAllEvent()
{
Events events= null ;
try {
events = service.events().list(this.calendarID).execute();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return events ;
}
How should I convert this function so that it will give only event on that day which i specify. I tried a lot of way but in version 3 it's not working the way it use to in v2.
Any suggestion. Please Remeber that we are talking about google calender Api version 3.
Hi ya i found the answer to my ques so updating here for others.
This can be done. Though we do not have direct way we can do it using query parameter. Let say if we wanted events feed from today onwards and not earlier than today. Then we can do this.
Events events = service.events().list(calendarID).setTimeMin("2012-01-01T00:00:00Z").execute();
instead of
events = service.events().list(this.calendarID).execute();
which just give us all the feeds from way back till 2031.
For getting feeds in between dates use setTimemin and setTimeMax together
Hope this help someone cheers...
Listed below is the code to use the Calendar service for v3 of the Google API utilizing Oauth2. I am posting it, since it is documented incorrectly by Google on their site.
Calendar service3 = new Calendar(transport, jsonFactory, accessProtectedResource);
com.google.api.services.calendar.model.Calendar calendar = service3.calendars().get("primary").execute();
com.google.api.services.calendar.model.Events events = service3.events().list("primary").execute();
Sameer currently the API doesn't includes this feature. But you can make a feature request here Apps Apis issue tracker.
You shall get some positive reply soon as it is monitored by Google engineers themselves.
For my Java application, I am creating an instance of a user information object and populating it with a service that I don't control the source for.
The code looks like this:
// username given as parameter
UserInfo ui = new UserInfo();
try {
DirectoryUser du = LDAPService.findUser(username);
if (du!=null) {
ui.setUserInfo(du.getUserInfo());
}
} catch (Exception e) {
// Whatever
}
If LDAPService.findUser() can't locate a user, it will throw a NullPointerException and grind the rest of my application to a stop. It's okay if the user information isn't populated, so I want to be able to continue without causing everything else to start throwing exceptions.
Is there a way to do this?
I've upvoted Amir Afghani's answer, which seems to be the only one as of yet that actually answers the question.
But I would have written it like this instead:
UserInfo ui = new UserInfo();
DirectoryUser du = null;
try {
du = LDAPService.findUser(username);
} catch (NullPointerException npe) {
// It's fine if findUser throws a NPE
}
if (du != null) {
ui.setUserInfo(du.getUserInfo());
}
Of course, it depends on whether or not you want to catch NPEs from the ui.setUserInfo() and du.getUserInfo() calls.
You could catch the NullPointerException explicitly and ignore it - though its generally not recommended. You should not, however, ignore all exceptions as you're currently doing.
UserInfo ui = new UserInfo();
try {
DirectoryUser du = LDAPService.findUser(username);
if (du!=null) {
ui.setUserInfo(du.getUserInfo());
}
} catch (NullPointerException npe) {
// Lulz # your NPE
Logger.log("No user info for " +username+ ", will find some way to cope");
}
You are already doing it in your code. Run this example below. The catch will "handle" the exception, and you can move forward, assuming whatever you caught and handled did not break code down the road which you did not anticipate.
try{
throw new Exception();
}catch (Exception ex){
ex.printStackTrace();
}
System.out.println("Made it!");
However, you should always handle an exception properly. You can get yourself into some pretty messy situations and write difficult to maintain code by "ignoring" exceptions. You should only do this if you are actually handling whatever went wrong with the exception to the point that it really does not affect the rest of the program.
It's generally considered a bad idea to ignore exceptions. Usually, if it's appropriate, you want to either notify the user of the issue (if they would care) or at the very least, log the exception, or print the stack trace to the console.
However, if that's truly not necessary (you're the one making the decision) then no, there's no other way to ignore an exception that forces you to catch it. The only revision, in that case, that I would suggest is explicitly listing the the class of the Exceptions you're ignoring, and some comment as to why you're ignoring them, rather than simply ignoring any exception, as you've done in your example.
You are actually ignoring exception in your code. But I suggest you to reconsider.
Here is a quote from Coding Crimes: Ignoring Exceptions
For a start, the exception should be logged at the very least, not
just written out to the console. Also, in most cases, the exception
should be thrown back to the caller for them to deal with. If it
doesn't need to be thrown back to the caller, then the exception
should be handled. And some comments would be nice too.
The usual excuse for this type of code is "I didn't have time", but
there is a ripple effect when code is left in this state. Chances are
that most of this type of code will never get out in the final
production. Code reviews or static analysis tools should catch this
error pattern. But that's no excuse, all this does is add time to the
maintainance and debugging of the software.
Even if you are ignoring it I suggest you to use specific exception names instead of superclass name. ie., Use NullPointerException instead of Exception in your catch clause.
You can write a try - catch block around the line you want to have ignored.
Like in the example code of yours. If you just continue your code below the closing bracket of the catch block everythings fine.
LDAPService should contain method like LDAPService.isExists(String userName) use it to prevent NPE to be thrown. If is not - this could be a workaround, but use Logging to post some warning..
Printing the STACK trace, logging it or send message to the user, are very bad ways to process the exceptions. Does any one can describe solutions to fix the exception in proper steps then can trying the broken instruction again?