How to avoid repeating try block - java

I'm coding a webservice in Java using aws and in many method i need to have a try catch block that can actually log any errors that can occur in the execution of each exposed methods.
#WebMethod(operationName = "listingBucket")
public String listingBucket() {
String message = "";
try {
message = "Listing buckets";
for (Bucket bucket : s3.listBuckets()) {
message += " - " + bucket.getName();
}
} catch (AmazonServiceException ase) {
message += "Caught an AmazonServiceException, which means your request made it "
+ "to Amazon S3, but was rejected with an error response for some reason.";
message += "Error Message: " + ase.getMessage();
message += "HTTP Status Code: " + ase.getStatusCode();
message += "AWS Error Code: " + ase.getErrorCode();
message += "Error Type: " + ase.getErrorType();
message += "Request ID: " + ase.getRequestId();
} catch (AmazonClientException ace) {
message += "Caught an AmazonClientException, which means the client encountered "
+ "a serious internal problem while trying to communicate with S3, "
+ "such as not being able to access the network.";
message += "Error Message: " + ace.getMessage();
}
return message;
}
#WebMethod(operationName = "addObjectToBucket")
public String addObjectToBucket(String bucketName, String objectName, File file) throws IOException{
if ( file == null ){
file = createSampleFile();
}
String message = "";
try {
message += "Uploading a new object to S3 from a file\n";
s3.putObject(new PutObjectRequest(bucketName, objectName, file));
} catch (AmazonServiceException ase) {
message += "Caught an AmazonServiceException, which means your request made it "
+ "to Amazon S3, but was rejected with an error response for some reason.";
message += "Error Message: " + ase.getMessage();
message += "HTTP Status Code: " + ase.getStatusCode();
message += "AWS Error Code: " + ase.getErrorCode();
message += "Error Type: " + ase.getErrorType();
message += "Request ID: " + ase.getRequestId();
} catch (AmazonClientException ace) {
message += "Caught an AmazonClientException, which means the client encountered "
+ "a serious internal problem while trying to communicate with S3, "
+ "such as not being able to access the network.";
message += "Error Message: " + ace.getMessage();
}
return message;
}
How Can i avoid to repeat this try catch block throw all methods that use this kind of stuff ?
Thanks for your help !
Edit : Actually I modified the code :
private String parseError(AmazonServiceException ase) {
String message;
message = "Caught an AmazonServiceException, which means your request made it "
+ "to Amazon S3, but was rejected with an error response for some reason.";
message += "Error Message: " + ase.getMessage();
message += "HTTP Status Code: " + ase.getStatusCode();
message += "AWS Error Code: " + ase.getErrorCode();
message += "Error Type: " + ase.getErrorType();
message += "Request ID: " + ase.getRequestId();
return message;
}
private String parseError(AmazonClientException ace) {
String message;
message += "Caught an AmazonClientException, which means the client encountered "
+ "a serious internal problem while trying to communicate with S3, "
+ "such as not being able to access the network.";
message += "Error Message: " + ace.getMessage();
return message;
}
#WebMethod(operationName = "listingBucket")
public String listingBucket() {
String message = "";
try {
message = "Listing buckets";
for (Bucket bucket : s3.listBuckets()) {
message += " - " + bucket.getName();
}
} catch (AmazonServiceException exc) {
message += parseError(exc);
} catch (AmazonClientException exc) {
message += parseError(exc);
}
return message;
}
Clearer indeed ! :)
I'll just take a look about the command pattern to see if I can use it for this kind of application.

There are two aspects in here.
One thing is about the code repetition in the catch block; which can be easily turned into something like
public class ExceptionHandler {
public String buildMessageFor(AmazonServiceException ase) {
... }
public String buildMessageFor(AmazonClientException ase) {
... }
...
You can even unit test that thing very easily (where "naming" could be improved; but I guess the example should be good enough to get you going).
That would also make it easier in the future to turn from "pure string" messages into something else. You know, hardcoding user messages in source code is not the smartest thing to do.
The other part, the try/catch itself; somehow depends. You see, the try/catch is an essential part of your operations; so many people would argue that you simply keep that structure in your code. The only alternative would be to define some kind of interface like
public interface RunAmazonOperation {
public void run() throws Amazon...
}
Then you can write down all your operations as little classes implementing that interface; to be called by some framework that does the try/catch for you. If that is worth the price ... depends on your application.
In other words: if you turn to the "command" pattern; you might find it useful to define a variety of "commands"; implementing that interface; thus reducing the number of places with try/catch dramatically.

Just do it with methods. One possibility would look like:
String parseError(AmazonServiceException ase){
String message;
message = "Caught an AmazonServiceException, which means your request made it "
+ "to Amazon S3, but was rejected with an error response for some reason.";
message += "Error Message: " + ase.getMessage();
message += "HTTP Status Code: " + ase.getStatusCode();
message += "AWS Error Code: " + ase.getErrorCode();
message += "Error Type: " + ase.getErrorType();
message += "Request ID: " + ase.getRequestId();
return message;
}
String parseError(AmazonClientException ace){
String message;
message = "Caught an AmazonClientException, which means the client encountered "
+ "a serious internal problem while trying to communicate with S3, "
+ "such as not being able to access the network.";
message += "Error Message: " + ace.getMessage();
return message;
}
Now you can just write:
catch(AmazonServiceException exc){
message=parseError(exc);
}
catch(AmazonClientException exc){
message=parseError(exc);
}

Related

Add reaction in jda to Message by messageid

My problem is, that my code, especially tc.addReactionById(messageID, emote);, dont adds a reaction. The whole code is following!
if(args[0].equalsIgnoreCase(prefix + "system") && args[1].equalsIgnoreCase("radd")){
if(args.length == 6){
Message message = event.getMessage();
List<TextChannel> channels = event.getMessage().getMentionedChannels();
List<Role> roles = message.getMentionedRoles();
if(!channels.isEmpty() && !roles.isEmpty()){
TextChannel tc = event.getMessage().getMentionedChannels().get(0);
Role role = roles.get(0);
String messageIDString = args[2];
try{
long messageID = Long.parseLong(messageIDString);
String emote = args[5];
tc.addReactionById(messageID, emote);
eb.setAuthor("Oni System");
eb.setColor(Color.MAGENTA);
eb.setDescription(emote);
eb.setFooter("Oni System | ©ONI", "https://media.discordapp.net/attachments/810910771557957672/810927512892604416/Bot.png?width=676&height=676");
channel.sendMessage(eb.build()).queue();
LiteSQL.onUpdate("INSERT INTO reactionroles(guildid, channelid, messageid, emoji, roleid) VALUES(" + event.getGuild().getIdLong() + ", " + tc.getIdLong() + ", " + messageID + ", '" + emote +"', " + role.getIdLong() + ")");
} catch (NumberFormatException e) {
e.printStackTrace();
}
}
}
else{
eb.setAuthor("Oni System");
eb.setColor(Color.RED);
eb.setDescription(userMent + " bitte benutze !system radd <messageid> <#role> <channel> <emoji>");
eb.setFooter("Oni System | ©ONI", "https://media.discordapp.net/attachments/810910771557957672/810927512892604416/Bot.png?width=676&height=676");
channel.sendMessage(eb.build()).queue();
}
}
addReactionById is a RestAction in the JDA library, so you will need to queue the operation.
Replace
tc.addReactionById(messageID, emote);
with
tc.addReactionById(messageID, emote).queue();
Assuming the messageID and emote arguments are valid, the call to .queue() should process the reaction. In particular, emote needs to be one of either:
An Emote object created by JDA (usually these are custom server emotes), or
A Unicode string of the emoji you want to add
See the MessageChannel documentation for more info.

Can I get multiple response from micro Service which will Query MongoDB

I have Service which will give us response back by querying MongoDB on the basis of some parameter provided
#RequestMapping(value = "/custRef/{custRef}", method = RequestMethod.GET)
#ResponseBody
public ResponseEntity<String> getServiceId(#PathVariable("custRef") String custRef) throws InterruptedException {
System.out.println("Thread.currentThread().getName() :"+Thread.currentThread().getName());
String serviceId=//calling Mongo Service and getting the result
if(custRef == null) {
return new ResponseEntity<String>("No service id available for the given FO Id:" + custRef,HttpStatus.NOT_FOUND);
}
return new ResponseEntity<String>(serviceId,HttpStatus.OK);
}
I have another client which will call the above service by providing the proper parameter. I want to call the above service by using 10 threads. can I get the response back in same frequency from the above service or do I need to do any configuration on the server where above one is running
ExecutorService es = Executors.newFixedThreadPool(50);
for (RouterInfo router : listOfcpeRouterInfo){
Future<String> serviceIDS = es.submit(new CalculationTaskA(router.getCustomerRef(), rieClient));
}
#Override
public String call() throws Exception {
String currentThreadName = Thread.currentThread().getName();
log.info("##### [" + currentThreadName + "] <" + taskId + "> STARTIING #####");
// System.out.println("[" + currentThreadName + "] <" + taskId + ">
// Sleeping for " + sleepTime + " millis");
// TimeUnit.MILLISECONDS.sleep(sleepTime);
//
String serviceId = null;
try {
///
serviceId = rieClient.getObject(customerRef);
log.info("serviceId for given foid: " + customerRef + " is " + serviceId);
} catch (ParseException pe) {
log.error("error while parsing Data", pe);
}
log.info("****** [" + currentThreadName + "] <" + taskId + "> DONE ******");
return serviceId;
}
calling above service
enter code here
Inside getObject I am doing below
ResponseEntity<String> response=restTemplate.exchange(this.serviceIdUrl+"/{foId}",HttpMethod.GET,entity,String.class,foId);
By default, Spring Boot applications are multithreaded so your code sample
ExecutorService es = Executors.newFixedThreadPool(50);
for (RouterInfo router : listOfcpeRouterInfo){ Future serviceIDS = es.submit(new CalculationTaskA(router.getCustomerRef(), rieClient)); }
would only be needed in your "Mongo" Service if asynchronous calls are to be made by the "Mongo" service.

Trouble casting JMS Message as TextMessage

I'm using a QueueBrowser to get and then loop through an enumeration of messages on a JMS queue. When I try to cast msgs.nextElement() as a TextMessage, IntelliJ IDEA tells me:
java.lang.ClassCastException: weblogic.jms.common.ObjectMessageImpl cannot be cast to javax.jms.TextMessage
I'm very new to JMS and I'm not quite sure what weblogic.jms.common.ObjectMessageImpl is. Casting msgs.nextElement() to type Message seems to work fine. My code is below.
private void readQueueMessage() throws JMSException {
int counter = 0;
System.out.println("Starting the subscriber");
QueueBrowser queueBrowser = queueSession.createBrowser(queue);
Enumeration msgs = queueBrowser.getEnumeration();
//queueConnection.start();
System.out.println("Queue started");
if ( !msgs.hasMoreElements() ) {
System.out.println("No messages in queue");
} else {
while (msgs.hasMoreElements()) {
System.out.println(">>> message count: " + ++counter);
Message message = (Message)msgs.nextElement();
System.out.println("MessageID: " + message.getJMSMessageID() + "\tPriority: " + message.getJMSPriority() + "\tDeliveryMode: " + message.getJMSDeliveryMode());
System.out.println("Timestamp: " + message.getJMSTimestamp() + "\tJMSDestination: " + message.getJMSDestination() + "\tReplyTo: " + message.getJMSReplyTo());
System.out.println("Data: " + ((TextMessage)message).getText());
if (counter >= 3) break;
}
}
System.out.println("stopping the queue");
queueConnection.stop();
}
There are several different types of messages in JMS. You are trying to read a TextMessage that basically contains a String, but the message you are reading is in fact an ObjectMessage which contains a Java object. You should check if the message is a text message using instanceof TextMessage and either ignore it if it is something else or throw an exception.
The class weblogic.jms.common.ObjectMessageImpl is simply WebLogic's implementation of ObjectMessage.

not printing to textbox

I am trying to create a way of retrieving from a hashtable an authorID for the articleName that the user enters. Here is the code that is activated on the client's side when the user presses a button:
public String getAuthorID() // returns a String
{
try
{
articleName = txtArticleName.getText();
argAuthorID = new Vector();// create vector for the args
argAuthorID.addElement(articleName);// name to search for to get AuthorID
// make the call to the server
authorIDVector = (Integer)client.execute("GetSize.sendAuthorID", argAuthorID);
System.out.println(argAuthorID);
}
catch (XmlRpcException exception) {
System.err.println("JavaClient: XML-RPC Consumer Fault #" +
Integer.toString(exception.code) + ": " +
exception.getCause() + "" + exception.toString());
} catch (Exception exception) {
System.err.println("JavaClient: XML-RPC Consumer Fault #" + exception.toString());
}
String StrAuthorID = Integer.toString(authorID); // Cast AuthorID to String
return StrAuthorID;
}
This is the method on the server side:
public int sendAuthorID(String articleNameRequest) {
// get info from the hashtable
aNumber = (Integer) theHashtable.getAuthorID(articleNameRequest); // was this.
return aNumber;
}
This is the code in the class that contains the hashtable:
public int getAuthorID(String articleName)
{
int intfoundit;
String foundit = (String)hashtab.get(articleName);
System.out.print(foundit);
intfoundit = Integer.parseInt(foundit);
System.out.print(foundit);
System.out.print(intfoundit);
return intfoundit;
}
The program can retrieve the AuthorID but won't input it into the textbox. Via testing I discovered that the exception was thrown by this code:
catch (XmlRpcException exception) {
System.err.println("JavaClient: XML-RPC Consumer Fault #" +
Integer.toString(exception.code) + ": " +
exception.getCause() + "" + exception.toString());
This is the error that is given:
'JavaClient: XML-RPC Consumer Fault #0:
nullorg.apache.xmlrpc.XmlRpcException: java.lang.Exception:
java.lang.NumberFormatException: For input string: " 3377"'
UPDATE: removed the space before the ID number in the hashtable and it doesn't throw an error anymore but it still isn't inputting the ID number into the textbox instead it just inputs a '0'
It seems to be failing in cases when you have spaces in your string. As we can see in your exception trace that parseInt failed to parse " 3377" and it threw NumberFormatException while executing:
intfoundit = Integer.parseInt(foundit);
So you may try to trim the string and see whether it solves your problem:
intfoundit = Integer.parseInt(foundit.trim());
Better you should do the trim where you are saving/putting the key/value in the hashtable.
The answer to the first problem was space before ID number on the hashtable because the space couldn't be converted to an Integer.
The answer to the second problem was that the following line was trying to convert the wrong variable
String StrAuthorID = Integer.toString(authorID); // Cast AuthorID to String
because the Integer was in the AuthorID variable
I corrected this by changing
authorIDVector = (Integer)client.execute("GetSize.sendAuthorID", argAuthorID);
to
authorID = (Integer)client.execute("GetSize.sendAuthorID", argAuthorID);

Restlet - Passing error status code and exception trace from server to client

We have a restlet server and client. We need to pass the error status and exception traces back to the client so that the client can take appropriate actions depending on the error status code. I read about StatusService and using response.setStatus() method but I can't get the specific exceptions thrown during server side processing be displayed on client side. The DAO layer from the server throws specific DB related exceptions and status code such as (Unique key violation etc), which the client needs to see and take appropriate actions.
Also, what is the common way of doing this to have centralized error handling / processing on server and client side ? Filters ?
A brief example will really help.
Thanks,
Deep
You can only send HTTP status codes and optionally your own description message. You can also send a representation of the error by overriding the getRepresentation in the StatusService.
#Override
public Status getStatus(Throwable throwable, Resource resource) {
Status ret = null;
Throwable cause = throwable.getCause();
if (cause == null) {
Status status = super.getStatus(throwable, resource);
ret = new Status(status, throwable.getMessage());
log.log(Level.SEVERE, "Unexpected resource exception <" + ret.toString() + "> for throwable of type <" + throwable + "> at resource <" + resource + ">");
} else if (cause instanceof NotFoundException) {
ret = new Status(Status.CLIENT_ERROR_NOT_FOUND, cause, resource.getReference().toString());
log.info("Not found <" + ret.toString() + "> for throwable of type <" + cause + "> at resource <" + resource + ">");
} else if (cause instanceof ConstraintViolationsException) {
ConstraintViolationsException e = (ConstraintViolationsException) cause;
ret = new Status(Status.CLIENT_ERROR_BAD_REQUEST, cause, e.getViolations().iterator().next().getMessage());
log.log(Level.SEVERE, "Constraint violation <" + e.getViolations().iterator().next().getMessage() + "> at resource <" + resource + ">");
} else if (cause instanceof BusinessRuleException) {
ret = new Status(Status.CLIENT_ERROR_BAD_REQUEST, cause, cause.getMessage());
log.log(Level.SEVERE, "Business rule exception: <" + cause.getMessage() + "> at resource <" + resource + ">");
} else {
Status status = super.getStatus(throwable, resource);
ret = new Status(status, throwable.getMessage());
log.log(Level.SEVERE, "Unexpected server exception <" + ret.toString() + "> for throwable of type <" + throwable + "> at resource <" + resource + ">");
}
return ret;
}
#Override
public Representation getRepresentation(Status status, Request request, Response response) {
String ret = "";
if (status.getDescription() != null) {
ret = status.getDescription();
} else {
ret = "unknown error";
}
return new StringRepresentation(ret, MediaType.TEXT_PLAIN);
}
You can return a representation of the error in getRepresentation in whatever format (XML, JSON, HTML) you want.

Categories