I have c#.net code which calls a method from another external/referenced .net assembly. This method I am calling throws an exception if a certain property from the object I am passing it is null. Here it is in a nutshell:
public void Add(string key, object obj)
{
..
//if the Foo property from obj is null then
throw new Exception("Foo property is null or empty")
..
}
In my client code which calls the DLL's Add method, I would like to be able to detect that this particular exception was raised, maybe distinguished by its "Foo property is null or empty" message. Currently, I get a NullReferenceException when it hits this method, so I catch this exception.
Question1:
Can I get the error message associated with the exception being thrown by the code I am calling (in the referenced assembly)??
Question2:
Is this considered bad practice or maybe just atypical?
Obviously, I can disassemble the third-party DLL to discover that my obj I'm passing in must have this "Foo" property set. So, my question here is somewhat for the sake of exercise (and because I'm a n00b).
Catching System.Exception and showing the exceptions Message property is all I needed. At first, I kept getting a NullReferenceException with "Object reference not set to instant of an object" message at the Add method, but I was expecting to get an Exception with the message "Foo property is null or empty" error. Some condition changed in my code and I now get what I expect.
Related
I have two list objects and want to check that the first items of each are equal. However, I get a NullPointerException at this line:
assertEquals(instance.getPlane(0), planes.get(0));
This is the entire stack trace:
Testcase: testGetPlane(mypackage.PlaneTest): Caused an ERROR
null
java.lang.NullPointerException
at mypackage.PlaneTest.testGetPlane(PlaneTest.java:60)
(Line 60 is the assertion.)
Neither of those objects are null. I'm having a separate issue getting the debugger to work, so instead I added these printouts to my test case:
System.err.println("equals? " + instance.getPlane(0).equals(planes.get(0)));
System.err.println("equals? " + planes.get(0).equals(instance.getPlane(0)));
However, those lines executed without throwing any errors!
I've cleaned and built the project and restarted Netbeans, but still have this issue.
JUnit just calls expected.equals(actual), which should be exactly the same thing as my printouts that aren't throwing the error, right? Why would assertEquals throw a NullPointerException, but equals on the same objects would not?
(I was about to post the question alone when I discovered the fix, but since it was a pain I'm posting it anyways in hopes this may help someone else. I did not find any other questions which had this solution.)
The error is in fact caused by JUnit, when it tries to compose an error message.
In the format function, there are the lines:
String expectedString = String.valueOf(expected);
String actualString = String.valueOf(actual);
if (expectedString.equals(actualString)) { ... }
String.valueOf(Object obj) returns obj.toString() if obj is not null.
My object's toString method simply returned a "name" field, which was never set inside the test. So, the object was not null, but the function returned null. This caused the NullPointerException when JUnit tried to call expectedString.equals. Ensuring that toString never returns null fixed the error.
I have to create a a new exception (MultipleErrorException) which extends MySuperException class. I have another exception (SingleErrorException) which also extends MySuperException.
Looking at the pseudo code below:
for (a number of times)
try
call myMethod(myObject) that throws SingleErrorException
catch(SingleErrorException e)
add the caught SingleErrorException object to a
MultipleErrorException object where a mapping should
be created mapping myObject to SingleErrorException
I need to throw a single "MultipleErrorException" which holds a map (myObject-->SingleErrorExceptions).
Is there any other way to this rather than creating an initial MultipleErrorException object before the for loop, an then adding the mappings as the exceptions are caught?
Thanks
java.lang.Exception as such does not have any method to support your requirement.
If you need it, then one way is to add the Map variable in MultipleErrorException and setting the value of it, but again, editing the exception object is not good.
Instead, you can add the error messages to Map and return the map instead of throwing the exception from the method.
So im preparing for interviews and in one of Gayle Laakmans career Cup videos a guy is writing a simple method that takes in an array and does something with it. She mentions his lack of error checking so he adds in this line like so:
public int max(int[] array) {
if (array == null)
throw new NullPointerException();
//method body
}
Is it correct to manually throw a NPE exception like this, this exception will get thrown anyway in the method body as it will use the array reference at some point.
A possible advantage to this i can see is that it separates input invalidation from the method logic being invalid and somehow creating a null reference. Otherwise it is a little confusing and maybe IllegalArgumentException would work better?
There's nothing wrong with throwing NullPointerException as soon as you enter the method instead of waiting to detect it after some processing has already been done. If the method is going to fail, it might as well fail fast.
Joshua Bloch's Effective Java recommends throwing NullPointerException over IllegalArgumentException in this situation (Item 60: Favor the use of standard exceptions).
If a caller passes null in some parameter for which null values are prohibited, convention dictates that NullPointerException be thrown rather than IllegalArgumentException.
IllegalArgumentException should be thrown when an illegal non-null value is passed in.
Also have a look at java's own utility class java.util.Objects:
public static <T> T requireNonNull(T obj,
String message)
Checks that the specified object reference is not null and throws a customized NullPointerException if it is. This method is designed primarily for doing parameter validation in methods and constructors with multiple parameters, as demonstrated below:
public Foo(Bar bar, Baz baz) {
this.bar = Objects.requireNonNull(bar, "bar must not be null");
this.baz = Objects.requireNonNull(baz, "baz must not be null");
}
Type Parameters:
T - the type of the reference
Parameters:
obj - the object reference to check for nullity
message - detail message to be used in the event that a NullPointerException is thrown
Returns:
obj if not null
Throws:
NullPointerException - if obj is null
from https://docs.oracle.com/javase/7/docs/api/java/util/Objects.html
Conclusion
Whether or not you use this utility class is another question, but it definitely shows, that the team behind the Java language intended to use NullPointerException for these purposes.
I have a class DataFile which is the top level class that I am serializing. DataFile contains an ArrayCollection which in-turn contains objects which extend ArrayData, each which overrides readExternal in different ways.
Over the course of the development the ArrayData object from version 1.0 is now different than the ArrayData object in version 1.1.
This causes deserialization to fail, most often with a null object error.
This is expected behavior. What I would like to happen is that in cases where an error occurs the object would simply be ignored and we would continue deserialization.
To effect this I have thrown try..catch logic into the deserialization for the ArrayData
override public function readExternal(input:IDataInput):void {
try {
testvalue = input.readObject();
newTestValue = input.readObject(); //a value that is not a part of the file being deserialized
catch(e:Error){
//an error occurred, but just keep going
}
}
I was hoping that this would allow the deserialization chain to continue doing its thing and then would allow me to clean up the broken data after everything has been deserialized.
The problem I am now having is that the serialization of the ArrayCollection fails immediately after an error is caught in a bad ArrayData object with a index out of bounds error.
Error #2006: The supplied index is out
of bounds.
I have tried faking data in the catch portion of te ArrayData object but nothing works. I don't know why the error is bubbling up the deserialization chain and I do not know how to prevent this.
If anyone has any ideas on where I should go next in an attempt to resolve this issue I would appreciate the feedback.
Thanks,
Dan
If a class has a constructor which takes some value object as parameter and relies on this to do its initialization. How should it react if this object is null?
class SomeClass
{
private SomeData _data;
public SomeClass(SomeValueObject obj)
{
_data = obj.Data;
}
}
This is one example, but in general: How should a constructor act if it is given invalid parameters and therefore cannot do the construction properly? Should it just return without doing any initialization? Set the parameters to some default values? Throw an exception? Something else?
I'm sure the answer to this is "It depends", but are there any best practices etc?
A programmer should be able to assume an object was successfully created, unless an exception is raised. The type of exception depends on the argument, but should nonetheless be unchecked. The last thing you want is the constructor fail to build a valid object and not tell the caller about it.
I think using default values in a constructor is a dangerous habit.
A lot depends on your business logic. If your business logic requires SomeValueObject to be not null, meaning SomeClass could not be instantiated without SomeValueObject then the constructor should definitely throw an Exception, probably IllegalArgumentException.
Seems like this is Java, but in C++ it should definitively throw ( a std::invalid_argument even ).
See C++ FAQ Lite 17.2.
I guess that for Java it's exactly the same.
In the rare cases where throwing exceptions presents a too big of a overhead, you should return, and set a flag in the object that it didn't construct properly. Afterwards check a isValid() member function.
Throw a null argument exception.
If field is critical it should cast an exception to indicate that object shouldnt be used. If its not critical you can assign default values.
If an object can have invalid default values, then it should initialize to the default values and wait for initialization. E.g., foo.set_values(...). In this case, there should be a query of is_ready() or is_valid() to allow checking before use.
If an object can absolutely not be in an invalid data-state, then it should throw an exception.
Both of these cases are things I've encounted.