throw simple exception with message - java

There is simple way to throw exception with message in java ?
In the following method I check for types and if the type doesn't exist i want to throw message
that the type is not supported ,what is the simplest way to do that ?
public static SwitchType<?> switchInput(final String typeName) {
if (typeName.equals("java.lang.String")) {
}
else if (typeName.equals("Binary")) {
}
else if (typeName.equals("Decimal")) {
}
return null;
}

Use the Exception Constructor which takes a String as parameter:
if (typeName.equals("java.lang.String")) {
}
else if (typeName.equals("Binary")) {
}
else if (typeName.equals("Decimal")) {
}
else {
throw new IllegalArgumentException("Wrong type passed");
}

The standard way to handle an illegal argument is to throw an IllegalArgumentException:
} else {
throw new IllegalArgumentException("This type is not supported: " + typeName);
}
And try not to return null if you can avoid it.

this method cannot throw an exception really
because typeName in input parameter of function is a String already..

Related

Entity from Optional Object (Java 8)

I am having some issue while trying to pull an entity out of an ArrayList that holds and Optional. When I do a breakpoint I get the return below the code. I know I am close but lack the knowledge on how to pull the GrandClientDataCore#9463 out of the data being returned to me.
Edited to add the previous line before the for loop.
Error occured: java.util.Optional cannot be cast to net.glmhc.dmhwebservices.entities.GrandClientDataCores.
List<GrandClientDataCores> grandClientDataCoresList = getGrandClientDataCoreList(submitMode, grandClientDataCoreId);
for (GrandClientDataCores grandClientDataCores : grandClientDataCoresList) {
CDCPAErrors request = new CDCPAErrors();
request.setI(this.service.getRequestInfo(grandClientDataCores, submitMode, staff));
logToFile(outDir, String.format("req_%s.xml", new Object[] {grandClientDataCores}), request);
CDCPAErrorsResponse response = (CDCPAErrorsResponse)
getWebServiceTemplate().marshalSendAndReceive(getWebServiceUri(), request,
(WebServiceMessageCallback) new SoapActionCallback("http://tempuri.org/CDCPAErrors"));
logToFile(outDir, String.format("res_%s.xml", new Object[] {grandClientDataCoreId}), response);
DmhServicesCdcResponse responseObj = getResponse(submitMode, response);
this.service.saveResponse(grandClientDataCores, submitMode, responseObj, staff);
responses.add(responseObj);
}
This is the getGrandClientDataCoreList
protected List<GrandClientDataCores> getGrandClientDataCoreList(SubmitMode submitMode, String grandClientDataCore) throws Exception {
List<GrandClientDataCores> grandClientDataCoresList;
try {
grandClientDataCoresList = (List<GrandClientDataCores>) this.service.getGrandClientDataCoreList(submitMode, grandClientDataCore);
} catch ( Exception ex) {
throw new Exception(ex);
}
if (grandClientDataCore == null || grandClientDataCore.isEmpty()) {
throw new NoDataException("No CDC record to validate.");
}
return grandClientDataCoresList;
}
You have to invoke get() on the optional to retrieve its value. You cannot just cast Optional<T> to something else. According to the debug image, the declaration of grandClientDataCoresList looked like this:
List<Optional<GrandClientDataCores>> grandClientDataCoresList ...
Therefore you need something like this:
for (Optional<GrandClientDataCores> gcdcOpt: grandClientDataCoresList) {
GrandClientDataCores gcdc = gcdcOpt.get();
....
values in grandClientDataCores are of type Optional<GrandClientDataCores>.
Your actual error is here:
protected List<GrandClientDataCores> getGrandClientDataCoreList(SubmitMode submitMode, String grandClientDataCore) throws Exception {
List<GrandClientDataCores> grandClientDataCoresList;
try {
grandClientDataCoresList = (List<GrandClientDataCores>) this.service.getGrandClientDataCoreList(submitMode, grandClientDataCore);
^^^^^^^^^^^^^^^^^^^^^^^^^^^^
This cast is invalid
} catch ( Exception ex) {
throw new Exception(ex);
}
if (grandClientDataCore == null || grandClientDataCore.isEmpty()) {
throw new NoDataException("No CDC record to validate.");
}
return grandClientDataCoresList;
}
You will find that the actual type returned by this.service.getGrandClientDataCoreList is List<Optional<GrandClientDataCores>> so you must update your code accordingly, in a number of places. For starters...
protected List<Optional<GrandClientDataCores>> getGrandClientDataCoreList(SubmitMode submitMode, String grandClientDataCore) throws Exception {
List<Optional<GrandClientDataCores>> grandClientDataCoresList;
try {
grandClientDataCoresList = this.service.getGrandClientDataCoreList(submitMode, grandClientDataCore);
} catch ( Exception ex) {
throw new Exception(ex);
}
if (grandClientDataCore == null || grandClientDataCore.isEmpty()) {
throw new NoDataException("No CDC record to validate.");
}
return grandClientDataCoresList;
}
and everywhere that you invoke this method.
use the "get()" function of Optional, which will retrieve the object itself.
pay attention it will throw an exception if no object was populated into this Optional.
GrandClientDataCores values in List are wrapped with Optional, so you have to check if value present:
grandClientDataCores.isPresent()
and if it is then just get it:
grandClientDataCores.get();
Alternatively, you can do something like that:
grandClientDataCores.orElse(new GrandClientDataCores())
And I recommend to read this

Is this a redundant NullPointerException catch?

Below Spring REST code returns List for a given ticketId.
Could a NullPointerException be thrown in this code ?
NullPointerException explicitly caught in TicketController:
catch (NullPointerException nullPointerException) {
throw new ResponseStatusException(
HttpStatus.BAD_REQUEST, nullPointerException.getMessage(), nullPointerException);
}
The thinking may have been when checking for null on the ticket id:
if (ticketId == null) {
throw new ResponseStatusException(HttpStatus.BAD_REQUEST, "ticket id cannot be null");
}
the expectation is that a NullPointerException would be thrown but instead a ResponseStatusException is thrown ?
If the variable ticketId is a path parameter it can never be null as hit the base url / without a ticketId I receive:
There was an unexpected error (type=Method Not Allowed, status=405).
Entire source:
#RestController
public class TicketController {
private final TicketServiceImpl ticketServiceImpl;
public TicketController(TicketServiceImpl ticketServiceImpl) {
this.ticketServiceImpl = ticketServiceImpl;
}
#GetMapping(path = "/{ticketId}")
public ResponseEntity<List<TicketResponse>> getTicketsById(
#PathVariable("ticketId") final Long ticketId) {
try {
final List<TicketResponse> ticketsById = ticketServiceImpl.getAll(ticketId);
return new ResponseEntity<>(ticketsById, HttpStatus.OK);
}
catch (NullPointerException nullPointerException) {
throw new ResponseStatusException(
HttpStatus.BAD_REQUEST, nullPointerException.getMessage(), nullPointerException);
}
catch (TicketNotFoundException ticketNotFoundException) {
throw new ResponseStatusException(
HttpStatus.NOT_FOUND, "Ticket id not found",
ticketNotFoundException);
}
}
}
#Service
public class TicketServiceImpl implements TicketService {
private final TicketRepository ticketRepository;
public TicketServiceImpl(TicketRepository ticketRepository) {
this.ticketRepository = ticketRepository;
}
#Override
public List<TicketResponse> getAll(Long ticketId) {
final List<TicketResponse> ticketResponselist = ticketRepository.findData(ticketId);
if (ticketId == null) {
throw new ResponseStatusException(HttpStatus.BAD_REQUEST, "ticket id cannot be null");
}
else if (ticketResponselist.size() == 0) {
throw new TicketNotFoundException("ticket not found");
}
else {
return ticketResponselist;
}
}
}
#Repository
public interface TicketRepository {
public List<TicketResponse> findData(Long ticketId);
}
The if (ticketId == null) check should happen before the ticketRepository.findData(ticketId); is called.
Otherwise, the validation doesn't make sense.
Also, as a side note, catching NullPointerException is a bad practice. The reason is that having a null pointer exception thrown is mostly a sign of a coding smell. The code should be null-safe, by either using e.g. Optional or having a proper validation at the method level. In this case, it would be at the route level (which is the external input). From that point onward, if the validation is set, you're dealing with non nullable id.
This is also somehow related to returning null from a method, which is also a bad practice, since it requires a check in every method which then uses the returned value. This would pollute the code, will introduce a new level of abstraction, and will generally lead to nasty bugs.
NullPointerException check is not required in this case.
Side note : Its better to use the super type when passing as a method parameter until and unless you are pretty sure that no exception will be thrown instead of yours.

Best way to parse DBXException java

So I recently asked the question of how to handle Dropbox API Exceptions here. I learned that I would have to parse the DBXEception into its subclasses which there are many of. Now Thinking about this I am wondering what would be the best way to go about handling this.
Currently I plan on using instanceof and checking like this if I want the program to try again it will return true and the program will try again maybe with a exponential backoff with server request
public boolean parseDBX(DbxException e)
{
if(e instanceof AccessErrorException) {//handle Error
}else if (e instanceof DbxApiException) {//handle Error
}etc
}
It would be called in a catch block like this
for(int i =0;;i++) {
try {
ListFolderResult result = client.files().listFolder("/Saves/"+prefName);
while (true) {
for (Metadata metadata : result.getEntries()) {
System.out.println(metadata.getPathLower());
//metadata.
}
if (!result.getHasMore()) {
break;
}
result = client.files().listFolderContinue(result.getCursor());
}
} catch (ListFolderErrorException e) {
createDefFolder();
} catch (DbxException e) {
if(codeHandler.parse(e)&&i<10) {
continue;
}else {
log.write("Error 5332490: a problem was encountered while trying to check for the root file"+e.getMessage());
throw new IOException();
}
}
}
So My Question is there a way to use a switch statement instead(From what I have found the answer is no), and if not, is there a better way to handle checking for the type of exception.
The best approach is to avoid "parsing" the exception at all by catching exceptions of the appropriate type:
try {
...
} catch (AccessErrorException aee) {
...
} catch (DbxApiException dae) {
...
}
In cases when this is not desirable you could associate your own integer ID with each exception type, put it in a Map, and use it in your parse method to distinguish among subtypes in a switch:
static Map<Class,Integer> parseId = new HashMap<>();
static {
parseId.put(AccessErrorException.class, 1);
parseId.put(DbxApiException.class, 2);
...
}
...
public void parseDBX(DbxException e) {
Integer id = parseId.get(e.getClass());
if (id != null) {
switch (id.intValue()) {
...
}
}
}

Java, Exception, the best way, exam preparations

I'm preparing for an exam in basic programming. I'm working on exceptions now but can't seem to figure out how to best use it. I give you the first code and then the second where I try to make a checked exceptions. Any input on this would make me grateful!
without the exceptions:
public boolean uttak(int species, int kroner, int skilling) {
if (species<=this.species && kroner<=this.kroner && skilling <=this.skilling)
{
this.species -=species;
this.kroner -=kroner;
this.skilling -=skilling;
return true;
}
else return false;
with my messy exceptions :
public void uttak(int species, int kroner, int skilling){
try{
if (species<=this.species && kroner<=this.kroner && skilling <=this.skilling)
{
this.species -=species;
this.kroner -=kroner;
this.skilling -=skilling;
}
}
catch (Exception e){
System.err.println ("Withdrawals can not be done when there is" +
" insufficient money in the machine.");
}
You probably are looking for something like this:
// custom checked exception type
public class WithdrawalException extends Exception {
public WithdrawalException(String msg) {
super(msg);
}
}
public boolean uttak(int species, int kroner, int skilling) throws WithdrawalException { // checked exceptions need to be declared in the throws clause
if (species<=this.species && kroner<=this.kroner && skilling <=this.skilling)
{
this.species -=species;
this.kroner -=kroner;
this.skilling -=skilling;
return true;
}
else
// throw an exception
throw new WithdrawalException("Withdrawals can not be done when there is insufficient money in the machine.");
}
And use it in the calling code like this
try {
uttak(i1, i2, i3);
} catch (WithdrawalException ex) {
System.err.println("Something went wrong. Message: "+ex.getMessage());
}
Neither of them is correct to me (if that's a topic about exceptions).
It is a good way to throw an unchecked exception when one of the method parameters doesn't satisfy logic of its method:
if (species > this.species || kroner > this.kroner || skilling > this.skilling) {
throw new IllegalArgumentException("message");
}
If you are encountered with a logical issue during the method execution, you should normally throw a checked exception (your own subclass of the Exception, or any other specific checked exception):
if (species > this.species || kroner > this.kroner || skilling > this.skilling) {
throw new MyCustomCheckedException("message");
}
There is no reason to handle an exception on this level (assuming that it is thrown somewhere in the try block, though it isn't in your case).

testng - creating KnownFault and IntermittentFailure annotations

I would like to annotate some of my test cases with KnownFault - which would do pretty much what expectedException does plus some magic using YouTrack's REST API. I would also like to have an IntermittentFailure attribute which would mean that I'm aware that the test might occasionally fail with [exception] [message] but I wouldn't want this to block the rest of my build chain.
After some research I found that my test class should implement IHookable, then I could have something like this:
#Override
public void run(IHookCallBack callBack, ITestResult result) {
callBack.runTestMethod(result);
if (result.getThrowable().getCause() instanceof IllegalArgumentException){
System.out.println("This is expected.");
result.setThrowable(null);
}
else{
System.out.println("Unexpected exception");
}
}
The problem with this is the actual implementation of invokeHookable:
final Throwable[] error = new Throwable[1];
IHookCallBack callback = new IHookCallBack() {
#Override
public void runTestMethod(ITestResult tr) {
try {
invokeMethod(thisMethod, testInstance, parameters);
} catch (Throwable t) {
error[0] = t;
tr.setThrowable(t); // make Throwable available to IHookable
}
}
#Override
public Object[] getParameters() {
return parameters;
}
};
hookable.run(callback, testResult);
if (error[0] != null) {
throw error[0];
}
Unfortunately that last line means that my test case is going to throw an exception no matter what as the error array is completely out of my hands in the run method.
So, what would be the proper way of intercepting an exception and handling it the way I want to?
What you are trying to do is really interesting. You should try to propose changes on https://github.com/cbeust/testng/pull/
But maybe IHookable is not the best listener you can use. Did you try IInvokedMethodListener?
void afterInvocation(IInvokedMethod method, ITestResult result) {
if (result.getThrowable().getCause() instanceof IllegalArgumentException) {
System.out.println("This is expected.");
result.setThrowable(null);
result.setStatus(SUCCESS); // If you want to change the status
} else {
System.out.println("Unexpected exception");
}
}

Categories

Resources