I have the following code.
This is the correct input which will not throw an error or exception.
{
name : "Hello"
age : 24
}
public APIGatewayProxyResponseEvent handleRequest(final APIGatewayProxyRequestEvent event, final Context context) {
String requestString = event.getBody();
JSONObject jsonObject = new JSONObject(requestString);
if (!Strings.isNullOrEmpty(jsonObject.getString("name")) {
//blah blah
} else {
(!Strings.isNullOrEmpty(jsonObject.getString("fullName")) {
//blah blah
}
{
fullName: "Hello"
age: 24
}
If I do not pass the name, but pass fullName I get an error
jsonObject.getString("name") is throwing an exception so my code never reaches the else block. What is the best way to read and process APIGatewayProxyRequestEvent. Both the request body are valid cases.
Thank you.
Related
I have a method something like this :
public Mono<SomeDTO> DoAction(SomeDTO someDTOObject) {
return findUser(someDTOObject.getUsername())
.flatMap(existingUser -> {
Update update = new Update();
return mongoTemplate.upsert(
Query.query(Criteria.where("username").is(someDTOObject.getUsername())),
update,
SomeDTO.class,
COLLECTION_NAME);
}).switchIfEmpty(
Mono.defer(() -> {
return Mono.error(new Exception("User Name doesn't exist."));
})
);
}
For this, I have wriiten a testcase like this to test exception :
#Test
public void DoAction_TestException() {
SomeDTO someDTOObject = databaseUtil.SomeDTOMock;
Query query = Query.query(Criteria.where("username").regex("^"+userId+"$","i"));
doReturn(Mono.empty()).when(mongoTemplate).findOne(query,
SomeDTO.class, "COLLECTION_NAME");
try {
SomeDTO someDTOObjectResult = mongoImpl.DoAction(someDTOObject).block();
}
catch (Exception e) {
String expected = "User Name doesn't exist.";
String result = e.getMessage().toString(); /////// this value during debugging is "java.lang.Exception:User Name doesn't exist. "
assertEquals(expected,result);
}
}
When I run the above code , the assert is failing becuase variable result has extra string along with it. How can I remove java.lang.Exception from the result ?
I dont want to use any string functions to remove part of string.ANy help would be very helpful.
If you're already in a catch clause, you're not dealing with Mono anymore.
In debugging you're checking e.toString(), which will be "java.lang.Exception:User Name doesn't exist. ".
But try to check behavior in a more isolated way.
public static void main(String[] args) {
Exception exception = new Exception("User Name doesn't exist.");
try {
throw exception;
} catch (Exception e) {
System.out.println("getMessage: " +e.getMessage());
System.out.println("toString: " + e.toString());
}
}
In this case e.getMessage() will print as expected User Name doesn't exist.
Eugene's answer is already showing you the correct way.
Alternate Solution #1:
Create a specific Exception class: EntityNotFoundException extends IOException or UsernameNotFoundException extends IOException and test if your result is an instance of that class.
Alternate Solution #2:
Extend your expected String expected to the String you really get.
Alternate Solution #3:
(I do not know Mono, so IF:) If Mono wraps up the Exception into another exception, you probably can reach that original exception by using e.getCause: Change your line String result = e.getMessage().toString(); to String result = e.getCause().getMessage();.
To help us find that out, simply add the line e.printStackTrace(); right after your line String expected = "User Name doesn't exist.";, and then show us what error message was printed. From there on we can help further, if the other solutions have not helped yet.
Is there any simple methods to return exception in JSON using Rest api?
I've already googled this question, but all solutions i see, was about throwing exceptions during some calculations. But what if income parameters are wrong? I mean what if there is sone string instead of int input parameter?
I created some DTO class for input data:
#XmlRootElement
public class RequestDTO implements Serializable{
private static final long serialVersionUID = 1L;
#XmlElement(name = "request_id")
private String requestId;
#XmlElement(name = "site")
private List<String> sitesIds;
#XmlElement(name = "date_begin")
#JsonSerialize(using = DateSerializer.class)
#JsonDeserialize(using = DateDeserializer.class)
private Date dateBegin;
#XmlElement(name = "date_end")
#JsonSerialize(using = JsonDateSerializer.class)
#JsonDeserialize(using = JsonDateDeserializer.class)
private Date dateEnd;
#XmlElement(name = "volume")
private double volume;
// there is getters and setters
}
If i sent something like 'qwerty' instead of 'volume' field in my json request i'l see error message like Runtime. Is it possible to handle it in someway? I mean to return error in json with such structure?
public class ExceptionDTO {
private String shortExceptionMessage;
private String stackTrace;
public ExceptionDTO(String shotExceptionMessage, String stackTrace){
this.shortExceptionMessage = shotExceptionMessage;
this.stackTrace = stackTrace;
}
public String getShortExceptionMessage() {
return shortExceptionMessage;
}
public String getStackTrace() {
return stackTrace;
}
}
UPD1:
#Provider
#Singleton
public class ExceptionMapperProvider implements ExceptionMapper<Exception>{
#Override
public Response toResponse(final Exception e) {
StringBuilder trace = new StringBuilder();
IntStream.range(0, e.getStackTrace().length)
.forEach(i -> trace.append(e.getStackTrace()[i]).append('\n'));
ExceptionDTO exceptionMessage = new ExceptionDTO(
e.toString(),
trace.toString()
);
return Response.status(500).entity(exceptionMessage).build();
}
}
As it's not really clear if you are interested on checking if field or value of the payload is correct, here are a few ways to work with both.
If you want to check if the value for a field is correct (ie volume field value should be greater than zero etc), check out bean validation. This makes use of annotations on the fields you want to verify.
// for example
#Min(value = 0, message = "invalid message")
private double range;
To use your ExceptionDTO as error response whenever one of those validation fails, you can do so by creating an ExceptionMapper<ConstraintViolationException>. check it here for more details.
If you are checking for the invalid field (ie client sends ragne fields instead of range), have a look at the stack trace on what exception is being thrown. Then register an exception mapper with your ExceptionDTO as body.
For example, if UnrecognizedPropertyException is thrown then you can add:
#Provider
public class UnrecognizedPropertyExceptionMapper implements ExceptionMapper<UnrecognizedPropertyException> {
#Override
public Response toResponse(UnrecognizedPropertyException e) {
ExceptionDTO myDTO = // build response
return Response.status(BAD_REQUEST).entity(myDTO).build();
}
}
If you want to validate input parameters in the request, you should return status code 400 (Bad Request) along with the error details. You can simply send json
{ "error": { "message": "string received for parameter x, where as int expected" } with the response status code 400.
`
I did a bit of research and determined that the best way to encode a Java exception in JSON is to use a convention developed by Oasis that looks like this:
{
"error": {
"code": "400",
"message": "main error message here",
"target": "approx what the error came from",
"details": [
{
"code": "23-098a",
"message": "Disk drive has frozen up again. It needs to be replaced",
"target": "not sure what the target is"
}
],
"innererror": {
"trace": [ ... ],
"context": [ ... ]
}
}
}
details is a list that should have an entry for each nested cause exception in the chain.
innererror.trace should include the stack trace if you wish, as a list of string values.
The response status code should be 400 unless you have a good reason for making it something else, and the code in the structure should match whatever you sent.
Write one method to convert a Java exception to this format, and you are done. Use it consistently and your JS code will be able to handle and display the exception values.
More of the details of the other approaches evaluated and dismissed are covered in this blog post on JSON REST API – Exception Handling
https://agiletribe.purplehillsbooks.com/2015/09/16/json-rest-api-exception-handling/
Here is the java method to convert an exception to this format:
public static JSONObject convertToJSON(Exception e, String context) throws Exception {
JSONObject responseBody = new JSONObject();
JSONObject errorTag = new JSONObject();
responseBody.put("error", errorTag);
errorTag.put("code", 400);
errorTag.put("target", context);
JSONArray detailList = new JSONArray();
errorTag.put("details", detailList);
String lastMessage = "";
Throwable runner = e;
while (runner!=null) {
String className = runner.getClass().getName();
String msg = runner.toString();
runner = runner.getCause();
JSONObject detailObj = new JSONObject();
detailObj.put("message",msg);
int dotPos = className.lastIndexOf(".");
if (dotPos>0) {
className = className.substring(dotPos+1);
}
detailObj.put("code",className);
System.out.println(" ERR: "+msg);
detailList.put(detailObj);
}
JSONObject innerError = new JSONObject();
errorTag.put("innerError", innerError);
JSONArray stackList = new JSONArray();
runner = e;
while (runner != null) {
for (StackTraceElement ste : runner.getStackTrace()) {
String line = ste.getFileName() + ":" + ste.getMethodName() + ":" + ste.getLineNumber();
stackList.put(line);
}
stackList.put("----------------");
runner = runner.getCause();
}
errorTag.put("stack", stackList);
return responseBody;
}
Hello I am using a webservice which returns a output upon completion of code execution. Is it possible that webservice may return the status in chunks like custom strings: Test Started, Test In Progress, Test Completed etc.
What I need to do to achieve this. Here is my current code where I am expecting a json string as input, supplied json is parsed and further processing is being performed.
//Class
public class WebserviceClient
{
/** calling constructor to initialize logger */
Utils c = new Utils();
Logger logger = Logger.getLogger(WebserviceClient.class.getName());
#Path("/test")
#POST
#Consumes(MediaType.APPLICATION_JSON)
//#Produces(MediaType.APPLICATION_JSON)
public String processRequest(final String inputData)
{
String executionID = "NOT_FOUND" ;
String result = "";
try
{
/** creating a pool of threads to submit a task to a callable thread */
ExecutorService ex = Executors.newFixedThreadPool(5);
Future<String> futureObject = ex.submit(new Callable<String>() {
#Override
public String call() throws Exception
{
logger.info("Parsing Received Request: "+inputData);
String rID = new JSONObject(inputData).getString("id");
logger.info("Received Id: "+rID + " From Request: "+inputData);
if(new RunTest().isTestCompleted(rID))
{
return rID;
}
else
{
return "777";
}
}
});
result = futureObject.get();
if(futureObject.get()!=null)
{
ex.shutdown();
}
else{
logger.debug("call id: "+executionID +" result is not generated yet. ");
}
logger.info("call id && Result: "+result);
}
catch(Exception e)
{
logger.error("call id: "+executionID, e);
}
return result;
}
}
You need to do a continuous polling to the server at high frequency to achieve the current status.
For little more information have a look at the :
Continuous polling of output using spring ,rest and angular js
This includes design consideration of using WebSockets etc, but there is no straight forward solution that I'm aware of.
As the title says, I need a way(no matter if its complicated or not) to create a getData() method that would send request packet to the server > receive the message I already have the system setup but I have a problem with it that I only get the result in PluginMessageReceiveEvent Here's my code with explanations:
public String requestData(String path) {
SocketUtils.sendData("REQUEST|" + p.getPlayer().getUniqueId() + "|" + path, "playerconfig", "BUNGEE");
return /*Need to get data from the plugin message to here*/;
}
#EventHandler
public void onPluginMessageReceive(PluginMessageReceiveEvent e) {
if (e.getChannel().equalsIgnoreCase("playerconfig")) {
String[] args = e.getMessage().split("\\|");
String uuid = args[0];
String path = args[1];//Maybe a HashMap<Path, Data> but that would make the requestData() result return null because you don't get the data instantly.
String data = args[2].replace("_", " ");
if (uuid.equals(p.getPlayer().getUniqueId() + "")) {
return data; //I need to get this result on request data method.
}
}
}
A simple solution is to wait on a lock in the requestData and notify that lock in onPluginMessageReceive. Something like this:
synchronized(this) {
wait();
}
And in your receive method:
synchronized(this) {
notifyAll();
}
Make the data a member field of the class.
Look out for exception handling and syntax errors.
I am new to FIX. I have a FIX message:
8=FIX.4.4|9=122|35=D|34=215|49=CLIENT12|52=20100225-19:41:57.316|56=B|1=Marcel|11=13346|21=1|40=2|44=5|54=1|59=0|60=20100225-19:39:52.020|10=072|
and I am using quickfixJ.
Here is my class code:
public String getYear(Message aMessage, SessionID aSessionID){
try {
crack(aMessage, aSessionID);
} catch (Exception e) {
e.printStackTrace();
}
String year = String.valueOf(mUTCCal.get(Calendar.YEAR));
String begin = String.valueOf(BeginString);
return year + " " + begin;
}
and when I call this method I 2012 null
I tried all sorts of methods for different fields and I get null. I am confused about why I do not get null for the date and how do I make it interpret correctly the other fields?
quickfix.fix44.NewOrderSingle message;
message = new quickfix.fix44.NewOrderSingle();
SessionID session = new SessionID("beginString", "senderCompID", "targetCompID");
MyApp app = new MyApp("", "", "");
String result = app.myMessage(message, session);
System.out.println(result);
I do not understand where to input the string I have (up top) into message
public void onMessage(Message message, SessionID sessionID) throws FieldNotFound {
Header header = message.getHeader();
String FIX = header.getString(8);
System.out.println(FIX);
}
public void onMessage(quickfix.fix44.NewOrderSingle message, SessionID sessionID) throws FieldNotFound, UnsupportedMessageType, IncorrectTagValue {
Header header = message.getHeader();
String FIX = header.getString(8);
String a = message.getString(1);
System.out.println(a);
System.out.println(FIX);}
In order to correctly get and parse FIX messages via QuickFIX, you must:
Create your Application: http://www.quickfixengine.org/quickfix/doc/html/application.html
Implement FromApp(Message message, SessionID sessionID) method
Implement the cracked method for ALL your message types you will receive from your counterparty
The FromApp method can be very simple:
public void fromApp(Message message, SessionID sessionID)
{
crack(message, sessionID);
}
Now, in your example you have a message FIX 4.4 of type 35=D [NewOrderSingle]
Therefore, you MUST implement a method as follows:
public override void onMessage(QuickFix44.NewOrderSingle message, SessionID session)
{
base.onMessage(message, session);
}
Now into your method you can easily work with all the fields you need:
public override void onMessage(QuickFix44.NewOrderSingle message, SessionID session)
{
base.onMessage(message, session);
ClOrdID ordid = new ClOrdID();
message.get(ordid);
}
Please also take a look here: http://www.quickfixengine.org/quickfix/doc/html/receiving_messages.html