I am trying to query our database and map the results to a list of models. I am currently getting the following exception: Request type not supported: class com.amazon.rdsdataservice.ExecuteStatementRequest RequestID: Removed (Service: AWSRDSData; Status Code: 400; Error Code: BadRequestException; Request ID: Removed )
I wrote the rest of the code that queries the database and had no issues, this is the first instance where I am getting this exception.
Here is the method throwing the exception, it is occurring on the execute line.
public List<CompanyReportingTable> getCompanyReportingData(String monthsBack) {
List<CompanyReportingTable> reportingData = new ArrayList<>();
try {
Map<String, String> param = new LinkedHashMap<>();
param.put("monthsBack", monthsBack);
//Below is the line throwing the exception
reportingData = rdsDataClient.forSql(COMPANY_REPORTING_EXTRACTION_QUERY).withParameter(param).execute().mapToList(CompanyReportingTable.class);
} catch (Exception ex) {
LOGGER.error("Exception while querying company reporting data: " + ex.getMessage(), ex);
}
return reportingData;
}
I have made sure that the query is valid SQL and runs in the RDS query editor. I have been unable to find similar questions, any help would be appreciated.
Related
Let's say I have a code that does some DB work and has a happy path and the only unhappy flow, that only occurs when DB connection is down, like this:
public Report createReport(
String reportType, Report reportData, ReportUser reportUser, Timestamp createTs) {
KeyHolder reportIdHolder = new GeneratedKeyHolder();
try {
saveReportDetails(reportType, reportData, reportUser, createTs);
} catch (DataAccessException e) { <-------------- This extends RuntimeException
log.error(
"DataAccessException while trying to insert report with name {}",
reportData.getReportName(),
e);
throw e;
}
...
// More of the happy path code here
}
I've got a test for the happy path, but is it a good practice to test for the Runtime exception flow as well?
The app is a SpringBoot Rest app, so it doesn't die when the exception is rethrown after logging.
What is the best way to handle errors when using Spring's Jpa Repository deleteById(Long id) method?
By default the deleteById(), checks to see if the ID has an existing row in the database, if it doesn't it throws a org.springframework.dao.EmptyResultDataAccessException because it expects a row size of 1.
I first tried to use my Exception Handler to pick up on this exception, which worked fine but the message exposes my package and class name to the user when Spring returns the error message.
#ExceptionHandler(EmptyResultDataAccessException.class)
#ResponseStatus(HttpStatus.BAD_REQUEST)
protected ResponseEntity<RestApiError> handleEmptyResultDataAccessException(EmptyResultDataAccessException ex, HttpServletRequest request) {
RestApiError error = new RestApiError(HttpStatus.BAD_REQUEST, Map.of("message", ex.getMessage()), request.getRequestURI());
return new ResponseEntity<>(error, error.getHttpStatus());
}
ex.getMessage() returns:
No class net.demo.customerservice.model.CustomerLocation
entity with id 7 exists!
Instead I decided to catch EmptyResultDataAccessException, and then throw more useful exception and message where I call deleteById();
My current code:
public void delete(Long id) {
try {
repository.deleteById(id); // call Spring's Data JPA repository method deleteById
} catch (EmptyResultDataAccessException ex) {
throw new EntityNotFoundException("Location with ID: [" + id + "] was not found");
}
}
This works great, and returns a good error message to the user but it seems like a hack.
Is there any better way to handle the EmptyResultDataAccessException? I could also use the existsById() method before calling the delete method, but then I am using two queries.
Generally it's better to avoid catching exceptions throughout the code. If you can delegate exception handling to another class, you can handle errors consistently across your application in one place. You could use #ControllerAdvice for this:
#ControllerAdvice
class GlobalControllerExceptionHandler {
#ExceptionHandler(EmptyResultDataAccessException.class)
public ResponseEntity<> handleRecordNotFound(EmptyResultDataAccessException ex) {
LOG.trace("Record not found: {}", ex.getMessage());
RestApiError error = new RestApiError(HttpStatus.BAD_REQUEST, Map.of("message", "Record not found"), request.getRequestURI());
return new ResponseEntity<>(error, error.getHttpStatus());
}
}
The client knows which entity it requested to delete, so there's no need to include the id in the error message returned to the client. You could log the message with he id to the log file.
java with Amazon AWS NoSuchFieldError
Here is the console log:
Exception in thread "AWT-EventQueue-0" java.lang.NoSuchFieldError: INSTANCE
at org.apache.http.client.utils.URLEncodedUtils.parse(URLEncodedUtils.java:246)
at org.apache.http.client.utils.URLEncodedUtils.parse(URLEncodedUtils.java:225)
at org.apache.http.client.utils.URIBuilder.parseQuery(URIBuilder.java:95)
at org.apache.http.client.utils.URIBuilder.digestURI(URIBuilder.java:165)
at org.apache.http.client.utils.URIBuilder.<init>(URIBuilder.java:90)
at org.apache.http.client.utils.URIUtils.rewriteURI(URIUtils.java:138)
at org.apache.http.impl.client.DefaultRequestDirector.rewriteRequestURI(DefaultRequestDirector.java:353)
at org.apache.http.impl.client.DefaultRequestDirector.execute(DefaultRequestDirector.java:476)
at org.apache.http.impl.client.AbstractHttpClient.doExecute(AbstractHttpClient.java:863)
at org.apache.http.impl.client.CloseableHttpClient.execute(CloseableHttpClient.java:82)
at org.apache.http.impl.client.CloseableHttpClient.execute(CloseableHttpClient.java:57)
at com.amazonaws.http.AmazonHttpClient.executeOneRequest(AmazonHttpClient.java:837)
at com.amazonaws.http.AmazonHttpClient.executeHelper(AmazonHttpClient.java:607)
at com.amazonaws.http.AmazonHttpClient.doExecute(AmazonHttpClient.java:376)
at com.amazonaws.http.AmazonHttpClient.executeWithTimer(AmazonHttpClient.java:338)
at com.amazonaws.http.AmazonHttpClient.execute(AmazonHttpClient.java:287)
at com.amazonaws.services.s3.AmazonS3Client.invoke(AmazonS3Client.java:3826)
at com.amazonaws.services.s3.AmazonS3Client.invoke(AmazonS3Client.java:3778)
at com.amazonaws.services.s3.AmazonS3Client.listObjects(AmazonS3Client.java:610)
at net.pocketsurvey.cloud.Amazon.listObjectsInBucket(Amazon.java:93)
The bottom line is where my code hands over to Amazon's S3. The code is as follows:
public static ObjectListing listObjectsInBucket(String bucketName,
String key) throws Exception {
ObjectListing list = null;
AmazonS3Client client = Client.s3(Client.DESKTOP);
try {
boolean b_exists = client.doesBucketExist(bucketName);
boolean o_exists = client.doesObjectExist(bucketName, key);
if(b_exists) {
list = client.listObjects(bucketName, key);
}
} catch ( AmazonServiceException e){
String err = e.getErrorMessage();
e.printStackTrace();
} catch ( AmazonClientException e){
e.printStackTrace();
} catch ( Exception e){
e.printStackTrace();
}
return list;
}
'client.listObjects' is where it bombs out.
libraries used include:
aws-java-sdk-1.10.77.jar
httpclient-osgi-4.3.jar
org.apache.httpcomponents.httpcore_4.2.1.jar
'b_exists' is true but 'o_exists' returns as false even tho the key most definitely exists.
I am using credentials that work for other things such as email, and downloading a known object, i.e. a complete key string. But trying to get a listing using a partial key string (such as "hhs/") I get the above eror.
Also the 'catches' don't catch it.
The code currently runs on the UI thread but I have tried it on its own thread with similar results.
The platform is Windows 7.
Any help would be greatly appreciated.
Problem sorted - library mismatch.
'aws-java-sdk-1.10.77.jar' needs 'org.apache.httpcomponents.httpcore_4.4.4.jar' to bein the build path.
I have get an Internal server exception for getting mail information while using lutung's java API of mandrill. Here is my code.
public MandrillMessageInfo getMessageInfo(String id) {
MandrillApi mandrillApi = new MandrillApi("Your api key");
MandrillMessageInfo info = null;
try {
info = mandrillApi.messages().info(id);
log.debug("Message status-> Email {}, state: {}, timeOfSent: {} ", info.getEmail() ,info.getState(), TimeUtil.getLocalTimeString(info.getTs()));
} catch (Exception e) {
log.debug("Exception occurs while getting message info for id: {}, exception is: {} ", id, e.getMessage());
throw new MailServiceException(ErrorCodes.ERROR_INTERNAL_SERVER_ERROR, ErrorCodes.ERROR_MESSAGE_INTERNAL_SERVER_ERROR);
}
return info;
}
I see nothing wrong in your code. If your API key is right, the only reason this request will return an error is if you give a wrong id. You can verify that by issuing a messages/info api request directly on mandrill website using "Try It" button https://mandrillapp.com/api/docs/messages.JSON.html#method=info and pass the same message id, that you are giving via the program call.
Hope this helps,
I’m writing in order to get some help.
To be short, I’m trying to use com.unboundid.ldap.sdk (but it is not necessary - the same problem i get if i use oracle's javax.naming.ldap.*) to handle with ldap transactions, and I get the following error:
Exception in thread "Main Thread" java.lang.AssertionError: Result EndTransactionExtendedResult(resultCode=2 (protocol error), diagnosticMessage='protocol error') did not have the expected result code of '0 (success)'.
at com.unboundid.util.LDAPTestUtils.assertResultCodeEquals(LDAPTestUtils.java:1484)
at pkg.Main.main(Main.java:116)
My program is the following ( I’m using simple example from https://www.unboundid.com/products/ldap-sdk/docs/javadoc/com/unboundid/ldap/sdk/extensions/StartTransactionExtendedRequest.html ) :
public class Main {
public static void main( String[] args ) throws LDAPException {
LDAPConnection connection = null;
try {
connection = new LDAPConnection("***", ***, "***", "***");
} catch (LDAPException e1) {
e1.printStackTrace();
}
// Use the start transaction extended operation to begin a transaction.
StartTransactionExtendedResult startTxnResult;
try
{
startTxnResult = (StartTransactionExtendedResult)
connection.processExtendedOperation(
new StartTransactionExtendedRequest());
// This doesn't necessarily mean that the operation was successful, since
// some kinds of extended operations return non-success results under
// normal conditions.
}
catch (LDAPException le)
{
// For an extended operation, this generally means that a problem was
// encountered while trying to send the request or read the result.
startTxnResult = new StartTransactionExtendedResult(
new ExtendedResult(le));
}
LDAPTestUtils.assertResultCodeEquals(startTxnResult, ResultCode.SUCCESS);
ASN1OctetString txnID = startTxnResult.getTransactionID();
// At this point, we have a transaction available for use. If any problem
// arises, we want to ensure that the transaction is aborted, so create a
// try block to process the operations and a finally block to commit or
// abort the transaction.
boolean commit = false;
try
{
// do nothing
}
finally
{
// Commit or abort the transaction.
EndTransactionExtendedResult endTxnResult;
try
{
endTxnResult = (EndTransactionExtendedResult)
connection.processExtendedOperation(
new EndTransactionExtendedRequest(txnID, commit));
}
catch (LDAPException le)
{
endTxnResult = new EndTransactionExtendedResult(new ExtendedResult(le));
}
LDAPTestUtils.assertResultCodeEquals(endTxnResult, ResultCode.SUCCESS);
}
}
}
As you can see, I do nothing with the transaction: just start and rolling back, but it still not working.
Connection is ok, and I receive transaction id = F10285501E20C32AE040A8C0070F7502 BUT IT ALWAYS THE SAME - is it all wrigth???
If “// do nothing” replace with some action exception: unwilling to perform.
I’m starting to think that it is OID problem, but I just can’t figure out what is wrong…
OID is on a WebLogic server and it’s version is :
Version Information
ODSM 11.1.1.6.0
OID 11.1.1.6.0
DB 11.2.0.2.0
All ideas will be appreciated.