I'm developing a J2ME Application and I want to make a good practice for Exception Handling, I'm throwing some exceptions like
ConnectionNotFoundException, IOException, XmlPullParserException, OutOfMemory, Exception
I don't want to catch all these exception in each method that I make
so I think that I can make a new class
and this class will handle all others
I have made this class
public class ExceptionHandler extends Exception {
private Exception thrownException;
public ExceptionHandler(Exception thrownExc) {
this.thrownException = thrownExc;
if (thrownException.getClass().isInstance(ConnectionNotFoundException.class)) {
// DO SOMETHING
} else if (thrownException.getClass().isInstance(IOException.class)) {
// DO SOMETHING
} else if (thrownException.getClass().isInstance(XmlPullParserException.class)) {
// DO SOMETHING
} else if (thrownException.getClass().isInstance(NullPointerException.class)) {
// DO SOMETHING
} else if (thrownException.getClass().isInstance(OutOfMemoryError.class)) {
// DO SOMETHING
} else if (thrownException.getClass().isInstance(Exception.class)) {
// DO SOMETHING
}
}
}
but I don't know if that is a good way or not and also I have error when I replace the thrown exceptions with mine
so what can I do please ?
You are on the right track, that is the best way to handle errors. You can also pass a second argument called message in your custom exception class and then display message here itself. Something like this:
if (thrownException.getClass().isInstance(ConnectionNotFoundException.class)) {
Dialog.alert(msg);
}
Also from the calling class, you just callnew ExceptionHandler(exception, Constants.msg)
The Constants.java class will hold all the error messages.
Related
So, by reading the NestJS documentation, I get the main idea behind how the filters work with exceptions.
But from all the code I have seen, it seems like all services always throw HttpExceptions.
My question is: Should the services really be throwing HttpExceptions? I mean, shouldn't they be more generic? And, if so, what kind of Error/Exception should I throw and how should I implement the filter to catch it, so I won't need to change it later when my service is not invoked by a Http controller?
Thanks :)
No they should not. An HttpException should be thrown from within a controller. So yes, your services should expose their own errors in a more generic way.
But "exposing errors" doesn't have to mean "throwing exceptions".
Let's say you have the following project structure :
📁 sample
|_ 📄 sample.controller.ts
|_ 📄 sample.service.ts
When calling one of your SampleService methods, you want your SampleController to know whether or not it should throw an HttpException.
This is where your SampleService comes into play. It is not going to throw anything but it's rather going to return a specific object that will tell your controller what to do.
Consider the two following classes :
export class Error {
constructor(
readonly code: number,
readonly message: string,
) {}
}
export class Result<T> {
constructor(readonly data: T) {}
}
Now take a look at this random SampleService class and how it makes use of them :
#Injectable()
export class SampleService {
isOddCheck(numberToCheck: number): Error | Result<boolean> {
const isOdd = numberToCheck%2 === 0;
if (isOdd) {
return new Result(isOdd);
}
return new Error(
400,
`Number ${numberToCheck} is even.`
);
}
}
Finally this is how your SampleController should look like :
#Controller()
export class SampleController {
constructor(
private readonly sampleService: SampleService
) {}
#Get()
sampleGetResponse(): boolean {
const result = this.sampleService.isOddCheck(13);
if (result instanceof Result) {
return result.data;
}
throw new HttpException(
result.message,
result.code,
);
}
}
As you can see nothing gets thrown from your service. It only exposes whether or not an error has occurred. Only your controller gets the responsibility to throw an HttpException when it needs to.
Also notice that I didn't use any exception filter. I didn't have to. But I hope this helps.
I am in the processing of learning Kotlin and ran into a problem I couldn't figure out.
I would like to extend the Java class RuntimeException in Kotlin and be able to use any one of three of its constructors, in different circumstances (based on what info I have at the time I want to throw an exception). In java my class would look like this:
public class PhotoLibException extends RuntimeException {
public PhotoLibException(String message, RuntimeException ex) {
super(message, ex);
}
public PhotoLibException(String message) {
super(message);
}
public PhotoLibException(RuntimeException ex) {
super(ex);
}
}
When I try to do this in Kotlin, I used this answer as a guide: Kotlin secondary constructor however, I had a problem trying to figure out how to invoke the appropriate super constructor correctly. For example, using functions seemed to be a good approach, like this:
fun PhotoLibException(message: String): PhotoLibException {
val ex = null
return PhotoLibException(message, ex)
}
fun PhotoLibException(ex: Exception): PhotoLibException {
val message = ""
return PhotoLibException(message, ex)
}
class PhotoLibException(message: String, ex: Exception?): RuntimeException(message, ex) {
}
However, in this Kotlin example above, I am always invoking the super constructor with two args, and not invoking the constructor most appropriate to the situation. So what I have above works, but doesn't do exactly what it would do in Java where a different constructor is invoked in each situation.
I also tried instantiating a new RuntimeException inside each fun above and casting it to PhotoLibException, but I wasn't allowed to do that.
Can anyone suggest how I would do this correctly in Kotlin?
Update: Since M11 (0.11.*), you can use secondary constructors to solve this problem:
class PhotoLibException : RuntimeException {
constructor(message: String, ex: Exception?): super(message, ex) {}
constructor(message: String): super(message) {}
constructor(ex: Exception): super(ex) {}
}
Currently, there's no way to call different super-constructors in different context from the same class. It will be supported in the upcoming months, though.
Use the #JvmOverloads annotation.
class PhotoLibException: RuntimeException {
#JvmOverloads constructor(message: String, ex: Exception?)
}
Per title, exceptions thrown from a ParamConverter are NOT handled the way I expect.
With an ExceptionMapper:
#Provider
public class MyExceptionMapper implements ExceptionMapper<MyException> {
#Override
public Response toResponse(MyException exception) {
return Response.serverError().entity( "It triggered" ).build();
}
}
and ParamConverter:
#Provider
(boilerplate junk)
#Override
public DateTime fromString(String value) {
throw new MyException("convert");
}
It does NOT return the "It triggered" text in a 500 error, but rather a 404.
Anticipated question : Are both providers registered?
Yes - If I throw "MyException" from a resource (within 'regular' code) it works as expected. I can also convert see the stacktrace with the "convert" message.
Is there any way to make exceptions from ParamConverters be handled by the ExceptionMapper?
I am using jersey 2.3.1, along with spring-jersey, launched in a jetty container 9.1.0.RC0
Seem from reading this, the JAX-RS spec says the implementor should wrap unhandled exceptions in a NotFoundException (404) for #QueryParam and #PathParam, and from what I tested a 400, (I'm guessing BadRequestException) for #FormParam.
"if the field or property is annotated with #MatrixParam, #QueryParam or #PathParam then an implementation MUST generate an instance of
NotFoundException (404 status) that wraps the thrown exception and no entity"
A couple ways I can see handling the exception, is to
Just handle it in the ParamConverter, e.g.
return new ParamConverter<T>() {
#Override
public T fromString(String string) {
try {
return (T)new MyObject().setValue(string);
} catch (MyException ex) {
Response response = Response.serverError().entity("Boo").build()
throw new WebApplicationException(response);
}
}
#Override
public String toString(T t) {
return t.toString();
}
};
Or just have your exception extend WebApplicationException, and return the Response there. e.g.
public class MyException extends WebApplicationException {
public MyException(String message) {
super(Response.serverError().entity(message).build());
}
}
I experienced the same behavior in Jersey 2.26.
Any Exception that extends RuntimeException gets mapped to a ParamException, which is itself a sublcass of WebApplicationException.
Assuming your MyException extends RuntimeException, it's not getting caught because your ExceptionMapper only handles MyException.
Regarding the Jersey docs saying to throw a NotFoundException: I would argue a 404 does not apply when a queryParam can't be converted. A BadRequestException seems more appropriate. And also, I can't see anything unique in the Jersey frame work when a NotFoundException is thrown besides setting the response code
To get exceptions thrown from a ParamConverter end up in an ExceptionMapper, you'll have to have your ExceptionMapper catching a more global exception, like Throwable.
Another answer suggests returning a WebApplicationException. This should be a fine solution but will NOT work if the Response object has an entity. See here: https://github.com/jersey/jersey/issues/3716
I start learning Caliburn.Micro and I am little confuse of handling with exception/messange box in view model class.
I found some blogs about, for example:
http://frankmao.com/2010/11/18/handling-messagebox-in-caliburn-micro/
For example some method in view model class which can produce exception.
public void MethodWichCanProduceEx(string arg1, string arg2 )
{
if(arg1==null)
throw new ArgumentNullException("arg1 is null");
if (arg2 == null)
throw new ArgumentNullException("arg2 is null");
try
{
}
catch (Exception exception)
{
throw exception;
//? show message box MessageBox.Shox(exception.Message)
}
}
What is correct handling and showing these exception in view ? It exist any kind of pattern for caliburn.micro?
It possible trace exception as in .NET in text, xml file ?
For example I would like trace exception in xml, text file and in view show only message.box or something message.
Thank for advance, maybe is my question little stupid, sorry I am only learning calibur.micro.
You'll want to always work against abstractions in your view models, in the case of message boxes, you don't want to have to wait for user input when you come to unit test your view models.
The Frank Mao code you linked to uses a delegate to abstract the implementation of the message box from the view model, but I would use an interface here. You can think of a delegate as an interface with a single method, but the advantage of using an interface in this context is that you can have different methods depending on the type of message you wish to show. For example, you could have a ShowMessageError, ShowMessageWarning, ShowMessageInfo etc.
So, define a contract for your message box:
public interface IMessageBox
{
void ShowException(Exception exc);
}
Inject the message box dependency into your view model, e.g. via the constructor
public class MyViewModel
{
private readonly IMessageBox messageBox;
public MyViewModel(IMessageBox messageBox)
{
this.messageBox = messageBox;
}
public void MethodThatCanThrowException()
{
try {}
catch(Exception exc)
{
// log the exception here
...
// show message box
this.messageBox.ShowException(exc);
}
}
}
You can then implement the message box anyway you wish, either using the windows system message box, or nicer still use your own view/viewmodel to display the message, perhaps using the Caliburn.Micro WindowManager.ShowDialog().
An implementation that uses the windows system message box may look like:
public class StandardMessageBox : IMessageBox
{
public void ShowException(Exception exception)
{
MessageBox.Show(exception.ToString(), "Error Occurred");
}
}
In production code, you can register StandardMessageBox against the IMessageBox interface in your IoC container.
In unit test land, you can mock out IMessageBox and have it do nothing, or in the case of methods with a result from the message box, always return a value you wish.
For logging the exception, I would look at a logging framework such as log4net (http://logging.apache.org/log4net/index.html) or NLog (http://nlog-project.org/)
Let's assume we have the following method in the business layer. What's the best practice to tell the UI layer that something went wrong and give also the error message? Should the method return an empty String when it was OK, otherwise the error message, or should it throw another exception in the catch code wrapping the caught exception? If we choose the second variant then the UI should have another try,catch which is too much try,catch maybe. Here is a pseudocode for the first variant.
public String updateSomething()
{
try
{
//Begin transaction here
dataLayer.do1();
dataLayer.do2();
dataLayer.doN();
//Commit transaction code here
}
catch(Exception exc)
{
//Rollback transaction code here
return exc.message;
}
return "";
}
Is this a good practice or should I throw another exception in the catch(then the method will be void)?
I like to return a standard contract to my UI layer from my business layer.
It looks like this:
public class ServiceOperationResult<T>
{
public bool Successful
{
get;
set;
}
public ServiceErrorType ErrorType
{
get;
set;
}
public string ErrorMessage
{
get;
set;
}
public T ReturnData
{
get;
set;
}
}
I use generics so that every service can define what it sends back, and the standard error flags tell the client app what type of error occurred (these are a meta-type, like "Internal error", "External party error", "Business rule validation error") and the app can then react in a standard fashion to these error types.
For instance, business errors are displayed in a red error label, while internal errors get redirected to an error page (in a web app) or close the form (in a windows app)
My pet hate is seeing a red label on a web site (where I expect to see validation errors) and seeing something like "The database server refused your connection" This is the risk that you run by only using a string to return error data.
The best way is wrap exception in some more general type and rethrow it. So updateSomething() must declare that it can throw some sort of Exception (for example: UpdateFailedException) and in catch block you should wrap exception.
public String updateSomething() {
try {
[...]
} catch ( SQLException e ) {
// rollback;
throw new UpdateFailedException(e);
}
}
But catching abstract Exception type is not a good idea. You should wrap only those things which semantic you know. For example: SQLException, DataAccessException (Spring DAO) etc.
If you wrap Exception you easily could wrap InterruptedException of NullPointerException. And this can broke your application.
It's a little unusual to return a String like this (but there's no real reason not too). More usual methods would be:
return a boolean value, and have some method of setting the error message, either by logging it, setting some global "last error" value, or having a pointer to an error construct passed in to your method which you update;
have a void method which throws an exception on failure, and handle it in the calling code (as you suggest)
I have see both of the above used extensively. It's hard to say which is "best". Try to be consistent with the idioms and conventions of the language you are working in and/or the existing code set/libraries you are working with if any.
Probably the best way is to have a custom exception classes specific to layers, once you catch the exception in a particular layer throw the custom exception to the calling layer, having this will have you the following advantage.
you will get the better modular approach to deal with the exception.
the maintenance of the code will be easy when your code complexity increases
you will be having more control on the exception scenarios
for example you catch a exception in the business layer and want to inform Presentation layer
public string DummyFunction
{
try
{
}
catch(Exception ex)
{
throw new businessException();
}
}