Excuses to my silly question, i wish to use a catch for specific exception, NSInvalidArgumentException, so, i have the next code in my OSX project:
#try
{
...
}
#catch(NSInvalidArgumentException* exception )
{
...
}
but xcode say me: "unknown type name 'NSInvalidArgumentException'", so i i was importing
import "Foundation/Foundation.h" or
import "Foundation/NSException.h"
but nothing happen, somebody known in what package or library is NSInvalidArgumentException? or which is my error? or is strictly necessary catch all exception using the superclass NSException? in the developer documentation do not show that so be it.
best regards.
NSInvalidArgumentException is not an exception type. It is a string that will be returned in the name property for an exception. So, you should catch your exception, and the name property does not match, you can re-#throw the exceptions you're not going to handle, e.g.:
#try {
// code that generates exception
}
#catch (NSException *exception) {
if ([exception.name isEqualToString:NSInvalidArgumentException])
{
// handle it
}
else
{
#throw;
}
}
See the Exception Programming Topics for more information.
I must confess that I share CodaFi's concern that this is not an appropriate use of exceptions. It's much better to program defensively, validate your parameters before you call Cocoa methods, and simply ensure that you don't generate exceptions in the first place. If you refer to the Dealing with Errors section of the Programming with Objective-C guide, exceptions are intended for "programmer errors" and they say:
You should not use a try-catch block in place of standard programming checks for Objective-C methods.
somebody known in what package or library is NSInvalidArgumentException?
It is declared in the Foundation Framework, in NSException.h. As CodaFi wrote in the comment, it is not a type, it is a string constant, declared as FOUNDATION_EXPORT NSString * const NSInvalidArgumentException;
So importing more headers won't fix your problem, because #catch(NSInvalidArgumentException* exception ) is like writing #catch(#"A string constant"* exception ), you have an object, where a type is expected.
Having said that, don't use exceptions for flow control. Have a look at the last part of this answer on SO
Related
Suppose the following situation in Objective-C: an array of blocks.
So I want to run a block, I do:
myBlock block = blocks[0]();
Now imagine that this line runs inside a try:
myBlock block = blocks[0];
#try {
block();
} #catch {
// catch an error
}
Now imagine that I want add a line inside a block to force the catch.
What I did in objective-C was to add this line inside a block
[NSException raise:#"Failed" format:#"Failed", nil];
Now I want to do that in Swift
let myClousure = closures[0]
do {
myClosure!()
} catch {
}
The question is: what line should I add to a closure to force the same behavior, or in other words, to make the closure fail and the catch to be triggered?
Sorry if the question is stupid but I am new to Swift.
In Objective-C, you use #try/#catch blocks to handle ObjC exceptions such as the one you are raising. In Swift, you use do/catch blocks to catch Swift errors that are explicitly thrown from a "throwing" function. Only functions (and closures) marked with the "throws" keyword are allowed to throw an error, and if you call a function that can throw, you must handle the error.
If you have an array of closures, the type signature of the closure must specify that it can throw, e.g.
let blocks: [() throws -> Void] = // get some blocks
At this point, you can (and indeed must) handle any errors thrown by calling these blocks:
let block = blocks[0]
do {
try block()
} catch let error {
print(error)
}
Me and my friend have some arguement about Exceptions. He proposes to use Exception as some kind of transporter for response (we can't just return it). I'm saying its contradictory to the OOP rules, he say it's ok because application flow was changed and information was passed.
Can you help us settle the dispute?
function example() {
result = pdo.find();
if (result) {
e = new UniqueException();
e.setExistingItem(result);
throw new e;
}
}
try {
this.example();
} catch (UniqueException e) {
this.response(e.getExistingItem());
}
Using exceptions for application flow is a misleading practice. Anyone else (even you) maintaining that code will be puzzled because the function of the exception in your flow is totally different to the semantic of exceptions.
I imagine the reason you're doing this is because you want to return different results. For that, create a new class Result, that holds all information and react to it via an if-statement.
Each guide I find on swift 2.0 error handling shows handling errors on a custom class. I know how to do, try, catch but what I don't know is what to catch. I know I'm testing for certain enum to indicate the error but where or how do i find these error enums if i did not create the class?
Im using
class func JSONObjectWithData(_ data: NSData,
options opt: NSJSONReadingOptions) throws -> AnyObject
so it says it throws and I would like to handle that but what does it throw? how do I know what enums to catch in the catch block? No doubt I'm missing something obvious but you know what it's like when you just can't spot it?
thanks
For methods in the Apple frameworks look into the documentation and compare the method signature with its Objective-C equivalent.
In this specific case the Objective-C equivalent is
+ (id)JSONObjectWithData:(NSData *)data
options:(NSJSONReadingOptions)opt
error:(NSError * _Nullable *)error
so the object in the catch statement is an NSError object
do {
let jsonData = try JSONObjectWithData(someData, options:NSJSONReadingOptions())
} catch let error as NSError {
print(error)
}
And, if you guaranty it should returns object then you could use below code:
let jsonDataObject = try! JSONObjectWithData(someData, options:NSJSONReadingOptions())
Here, advantage is we can avoid to use "do { }" scope of syntax
Newbie question. Imagine a ParseTreeListener implementation with dozens of enter- and exit- methods which require exception handling. To avoid coding try-catch for each of these 40+ methods individually, I'd prefer a solution which would allow to catch listener's exceptions in a centralized manner and still have a reference to the context (line, position) where the exception was thrown, just like in the imaginary code below:
TestParser parser = new TestParser(tokens);
ParseTreeWalker walker = new ParseTreeWalker();
TestListener listener = new DefaultTestListener();
ParseTree tree = parser.entrynode();
try {
walker.walk(listener, tree);
} catch (RuntimeException e) {
LOG.info("Exception at " + tree.getContextWhereExceptionWasThrown());
}
Is it possible in any way?
Given that you have only shown imaginary code, you need to verify the true source and kind of the Exceptions you are seeing.
Walking an otherwise valid parseTree should not throw any Exception other than those you choose to throw. OTOH, the parser will throw exceptions of the type you seem to be concerned with.
If they are indeed parser exceptions, you can catch them explicitly as RecognitionException rather than RuntimeException exceptions. That exception object has the methods you seem to be looking for: getContext, getOffendingToken, etc.
If they are instead occurring in the execution of the walker, you will need to clarify your question regarding the type of exception. If you are throwing the exception, include the relevant token indexes and intervals, obtained from the TerminalNodes and ParserRuleContext objects in the then current context, in a 'one size fits all' exception.
In below code I want to neutralize the throw and continue the method - Can it be done ?
public class TestChild extends TestParent{
private String s;
public void doit(String arg) throws Exception {
if(arg == null) {
Exception e = new Exception("exception");
throw e;
}
s=arg;
}
}
The net result should be that, in case of the exception triggered (arg == null)
throw e is replaced by Log(e)
s=arg is executed
Thanks
PS : I can 'swallow' the exception or replace it with another exception but in all cases the method does not continue, all my interventions take place when the harm is done (ie the exception has been thrown)
I strongly doubt that general solution exists. But for your particular code and requirements 1 and 2:
privileged public aspect SkipNullBlockAspect {
public pointcut needSkip(TestChild t1, String a1): execution(void TestChild.doit(String))
&& this(t1) && args(a1) ;
void around(TestChild t1, String a1): needSkip(t1, a1){
if(a1==null) //if argument is null - doing hack.
{
a1=""; //alter argument to skip if block.
proceed(t1, a1);
t1.s=null;
a1=null; //restore argument
System.out.println("Little hack.");
}
else
proceed(t1, a1);
}
}
I think that generally what you want makes no sense most cases because if an application throws an exception it has a reason to do so, and that reason almost always includes the intention not to continue with the normal control flow of the method where the exception was thrown due to possible subsequent errors caused by bogus data. For example, what if you could neutralise the throw in your code and the next lines of code would do something like this:
if(arg == null)
throw new Exception("exception");
// We magically neutralise the exception and are here with arg == null
arg.someMethod(); // NullPointerException
double x = 11.0 / Integer.parseInt(arg); // NumberFormatException
anotherMethod(arg); // might throw exception if arg == null
Do you get my point? You take incalculable risks by continuing control flow here, assuming you can at all. Now what are the alternatives?
Let us assume you know exactly that a value of null does not do any harm here. Then why not just catch the exception with an after() throwing advice?
Or if null is harmful and you know about it, why not intercept method execution and overwrite the parameter so as to avoid the exception to begin with?
Speculatively assuming that the method content is a black box to you and you are trying to do some hacky things here, you can use an around() advice and from there call proceed() multiple times with different argument values (e.g. some authentication token or password) until the called method does not throw an exception anymore.
As you see, there are many ways to solve your practical problem depending on what exactly the problem is and what you want to achieve.
Having said all this, now let us return to your initial technical question of not catching, but actually neutralising an exception, i.e. somehow avoiding its being thrown at all. Because the AspectJ language does not contain technical means to do what you want (thank God!), you can look at other tools which can manipulate Java class files in a more low-level fashion. I have never used them productively, but I am pretty sure that you can do what you want using BCEL or Javassist.