I use JSLint all the time, but just today, I came across an error that I've never seen before. With the following code, I got the error shown below:
try {
document.execCommand('BackgroundImageCache', false, true);
} catch (ex) {}
Error:
Expected 'ignore' and instead saw 'ex'.
} catch (ex) {}
So I changed my code to the following, and the error went away:
try {
document.execCommand('BackgroundImageCache', false, true);
} catch (ignore) {}
I can't find any explanation on the Internet regarding why this would fix the error. Does anyone know what's up or why this fixed the problem?
Thank you.
I think you're right -- jslint didn't used to complain like this. Instead, it told you that you needed to do something with ex, right? I'll check github to see and edit this later. EDIT: Great catch [by you]! Crockford, JSLint's author, added this on April 29th of this year around line 3444. And he uses empty catch blocks in jslint's source, so I guess he has to give us the kludge too. ;^)
JSLint wants you to kludge empty catch blocks with ignore as the variable name so that it's obvious to people reading your code that you intentionally meant not to do anything in your catch block. As Crockford says elsewhere, he feels that, "It is difficult to write correct programs while using idioms that are hard to distinguish from obvious errors."
1.) ex used (okay)
So (as I'm guessing you know) if you write this code and do something with ex, jslint doesn't complain.
/*jslint browser: true, white:true, sloppy:true*/
var spam;
try {
spam = "spam";
} catch (ex) {
window.alert(ex);
}
2.) ex unused means ignore (okay too)
So if you mean not to do anything with ex, he wants the code to tell folks you didn't screw up by leaving your ex equivalent in there by naming that variable ignore.
/*jslint browser: true, white:true, sloppy:true*/
var spam;
try {
spam = "spam";
} catch (ignore) {
}
3.) ignore used (error!)
So, in typical Crockfordian fashion, you now can't use ignore and actually do something in the catch block!
/*jslint browser: true, white:true, sloppy:true*/
var spam;
try {
spam = "spam";
} catch (ignore) {
window.alert(ignore);
}
That gives
Unexpected 'ignore'. } catch (ignore) {
Just another hyper-explicit "don't make code that looks like an error" move by Crockford.
(Aside: Might be fun to take a look at Why are empty catch blocks a bad idea while you're on the subject. Honestly, though ignore is probably a useful convention, based on that discussion (I mean, it includes Skeet arguing against empty catch blocks!), I'm a little surprised Crockford allows the ignore kludge, as the above link has arguments that feel a lot like his for calling some regular expressions "unsafe".)
Related
I want to run cleanup code after a certain block of code completes, regardless of exceptions. This is not a closeable resource and I cannot use try-with-resources (or Kotlin's use).
In Java, I could do the following:
try {
// ... Run some code
} catch(Exception ex) {
// ... Handle exception
} finally {
// ... Cleanup code
}
Is the following Kotlin code equivalent?
runCatching {
// ... Run some code
}.also {
// ... Cleanup code
}.onFailure {
// ... Handle exception
}
Edit: added boilerplate exception handling - my concern is with ensuring the cleanup code runs, and maintainability.
There is one important difference, where the code inside runCatching contains an early return. A finally block will be executed even after a return, whereas also has no such magic.
This code, when run, will print nothing:
fun test1()
runCatching {
return
}.also {
println("test1")
}
}
This code, when run, will print "test2":
fun test2() {
try {
return
} finally {
println("test2")
}
}
There is one big difference between both code samples. try...finally propagates exceptions while runCatching().also() catches/consumes them. To make it similar you would have to throw the result at the end:
runCatching {
// ... Run some code
}.also {
// ... Cleanup code
}.getOrThrow()
But still, it is not really 1:1 equivalent. It catches all exceptions just to rethrow them. For this reason, it is probably less performant than simple try...finally.
Also, I think this is less clear for the reader. try...finally is a standard way of dealing with exceptions. By using runCatching() just to immediately rethrow, you actually confuse people reading this code later.
Your question sounded a little like you believed Kotlin does not have try...finally and you need to search for alternatives. If this is the case, then of course Kotlin has try...finally and I think you should use it instead of runCatching().
As per Kotlin's doc for runCatching:
Calls the specified function block and returns its encapsulated result if invocation was successful, catching any Throwable exception that was thrown from the block function execution and encapsulating it as a failure.
Even if finally always runs after a try block and also always runs after a runCatching, they do not serve the same purpose.
finally doesn't receive any argument and cannot operate on the values of the try block, while also receives the Result of the runCatching block.
TLDR; .runCatching{}.also{} is a more advanced try{}finally{}
There is also a difference in what is the result of evaluating the expression.
Consider the following code:
fun main() {
val foo = try {
throw Exception("try")
} catch(e: Exception) {
"catch"
} finally {
"finally"
}
val bar = runCatching{
throw Exception("runCatching")
}.also{
"also"
}.onFailure {
"onFailure"
}
println(foo)
println(bar)
}
The output will be:
catch
Failure(java.lang.Exception: runCatching)
https://pl.kotl.in/a0aByS5l1
EDIT:
An interesting article that points out some differences as well:
https://medium.com/#mattia23r/a-take-on-functional-error-handling-in-kotlin-515b67b4212b
Now let’s give a second look at the implementation of runCatching in the gist above. What does it do? It catches everything.
In this case, it goes even further: it catches all Throwables. For those not knowing, Throwable is everything that can go after a throw keyword; it has two descendants: Exceptions and Errors. We haven’t mentioned Errors so far; Errors usually represent something wrong that happened at a lower level than your business logic, something that can’t usually be recovered with a simple catch.
I'm testing a function using Chai's expect ... not.to.throw pattern (v4.3.4):
describe('parseInt', () => {
it('does not throw TypeError', () => {
// foo is not defined, so a ReferenceError is thrown... somewhere?
expect(() => parseInt(foo)).not.to.throw(TypeError);
});
});
The closure throws an error, but I don't see this error anywhere in the output (running mocha). The test passes without the slightest indication of the problem inside the closure.
I expect to at least see the error in the console, even if the tests pass.
This answer says that such errors must be run like so:
// wrapping describe/it are elided
try {
expect(() => parseInt(foo)).not.to.throw(TypeError);
} catch (e) {
expect(e).to.be.a(ReferenceError); // should PASS, and does
}
This passes, but doesn't appear to be testing the second condition. I can flip it and the test still passes:
// wrapping describe/it are elided
try {
expect(() => parseInt(foo)).not.to.throw(TypeError);
} catch (e) {
expect(e).not.to.be.a(ReferenceError); // should FAIL, but does not
}
What am I missing?
Edit
I think the behavior you are observing is actually expected. The original post you referenced may be misleading.
Consider the following test:
// describe/it wrappers have been redacted
expect(()=>parseInt(foo)).to.not.throw(TypeError)
Should this test pass or fail? Intuitively it should pass since the assertion is met: a TypeError was not thrown.
Again for the following test, should 'hello there' be logged to the console?
// describe/it wrappers have been redacted
try {
expect(() => parseInt(foo)).to.not.throw(TypeError);
} catch (e) {
console.log('hello there')
}
If yes, then the statement expect(() => parseInt(foo)).to.not.throw(TypeError), must throw.
And for it to throw, the assertion - not throw a TypeError - must not be met, but we have already established that the assertion is met, and so no exception is thrown.
Therefore, all code in the catch block is unreachable.
This is why the second assertion in your original example is never executed. It will only be reached if the code somehow threw a TypeError and caused the assertion to fail.
Possible solution
For the approach you are taking, I think it could work if there was a way to tell mocha/chai to still go ahead and propagate the error that is thrown by the target function even if the assertion is met. I am unsure of if there is a way to do this, though.
Alternative approach
Alternatively, I think you can get the same (or similar) outcome for the test you have in mind by doing this instead:
// describe/it wrappers have been redacted
const myFunc = () => parseInt(foo)
expect(myFunc).to.not.throw(TypeError)
expect(myFunc).to.throw(ReferenceError)
Here are the assumptions underlying the above test:
You are expecting an error
The error should under no circumstances be a TypeError
The error thrown should always be a ReferenceError.
In case these assumptions do not match what you are currently testing for, or if my alternate approach does not satisfy your needs, kindly let me know!
PS, I used mocha: "^9.1.0" and chai: "^4.3.4" for these tests.
I'm new to Kotlin and I'm trying to do a simple task - create and write to a file. For some reason, using use() with a block function on printWriter() doesn't actually write.
File("test2.txt").printWriter().use { out ->
{
println("hmmm")
out.println("what's up")
log.info { "finished writing" }
}
}
In fact, the block function doesn't seem to be called at all - both "hmmm" and "finished writing" never show up, although the file itself is created (but is totally empty).
The much simpler writeText() works just fine - the file is created and the given text is written to the file.
File("test3.txt").writeText("testing")
What am I doing wrong in my use() version?
Edit: it seems to be a syntax issue with my block function. Looks like I have an extra pair of brackets? Would love a brief explanation as to why it makes it not work.
Edit 2: I think I understand now. The way I wrote it, I was essentially returning the block function itself rather than running through it.
So the problem was that the way I was writing the block function caused it to just return the inner block function, and not actually call it.
Here are two ways that work:
File("test2.txt").printWriter().use {
println("hmmm")
it.println("what's up")
log.info { "finished writing!" }
}
File("test2.txt").printWriter().use(fun(out) {
println("hmmm")
out.println("what's up")
log.info { "finished writing!" }
})
Although, for my purposes writeText() actually works just fine and is much shorter haha.
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.
I have the following coding
try
{
var foundCanProperty = properties
.First(x => x.Name == "Can" + method.Name);
var foundOnExecuteMethod = methods
.First(x => x.Name == "On" + method.Name);
var command = new Command(this, foundOnExecuteMethod, foundCanProperty);
TrySetCommand(foundControl as Control, command);
}
catch (InvalidOperationException ex)
{
throw new FatalException("Please check if you have provided all 'On' and 'Can' methods/properties for the view" + View.GetType().FullName, ex);
}
I'd expected that if the methods.First() (in second var statement) throws an InvalidOperationException, I'd be able to catch it. But this seems not be the case (catch block is ignored and the application terminates with the raised exception). If I throw myself an exception of the same type within the try block, it gets caught. Does Linq use multihreading so that the exception is thrown in another thread? Perhaps I make also a stupid error here and just do not see it :(.
Thanks for any help!
I know that this isn't an answer, but rather some additional steps for debugging, but does it change anything if you instead try to catch the general type "Exception" instead of the IOE? That may help to isolate if the method is truly throwing an IOE, or if its failure is generating an IOE somewhere else in the stack. Also - assuming this method isn't in main() - is there a way to wrap the call to it in a try/catch and then inspect the behavior at that point in the call flow?
Apologies, too, in that I know very little about the SilverLight development environment so hopefully the suggestions aren't far fetched.
InvalidOperationException exception occures when The source sequence is empty.
refere to http://msdn.microsoft.com/en-us/library/bb291976.aspx
check weather "properties" or "methods" is not empty.
out of interest, Why you not using FirstOrDefault ?