I've recently found that Kotlin supports try-catch-finally expressions (in the same vein as switch expressions). They seem particularly useful to me when executing a block that will assign to a variable or assign a default if the block fails, like this:
fun main (args: Array) {
val str="23"
val a: Int? = try { str. toInt () } catch (e: NumberFormatException) {-1}
println (a)
}
I think this is the first time I see this feature in a programming language, and as usual I've been thinking about how to simulate it, in this case in JavaScript. We can easily simulate the try-catch expression with a tryFn function (emulating try-catch-finally would be more complicated).
function tryFn(fn, exceptions, onErrorFn){
try{
return fn();
}
catch (error){
if (exceptions.some(exception => error instanceof exception)){
return onErrorFn(error)
}
else{
throw error;
}
}
}
//val = tryCatch(fn1, [Error1, Error2], onErrorDefaultFn)
We can use this function like this:
class InvalidUrlError extends Error{}
class InvalidPostError extends Error{}
class InvalidUserError extends Error{}
function getPost(url, postId, user){
if (!url)
throw new InvalidUrlError("Wrong URL")
if (!postId)
throw new InvalidPostError("Wrong Post")
if (!user)
throw new InvalidUserError("Wrong User")
return `Post ${postId} by {user} content`;
}
function formatPost(post){
return `[[[${post}]]]`;
}
let infos = [
["server.org", "1", "xuan"],
[null, "1", "xuan"],
["server.org", null, "xuan"],
//["server.org", "2", null],
["server.org", "3", "xuan"]
]
for (let info of infos){
let post = tryFn(() => formatPost(getPost(...info)),
/*catch*/ [InvalidUrlError, InvalidPostError], (ex) => {
console.log(`caught error: ${ex.constructor.name}`);
return "No Post"
}
);
console.log(`post: ${post}`)
}
Well, not sure I will ever use it, but I think it's a valid attempt.
This reminds me a bit of cases where combining await and .catch() for async code rather than wrapping the async call in a try-catch makes the code cleaner. I'm talking about this
No comments:
Post a Comment