I'm probably overlooking something simple, but I do not expect the below code to fail. It is behaving as if I wrote die instead of fail in the catch block.
The Failure does not get properly handled and the code dies.
sub foo()
{
try {
say 1 / 0;
CATCH { default { fail "FAIL" } }
}
return True;
}
with foo() {
say "done";
}
else
{
say "handled {.exception.message}"
}
Output:
FAIL
in block at d:\tmp\x.pl line 5
in any at d:\tmp\x.pl line 5
in sub foo at d:\tmp\x.pl line 4
in block <unit> at d:\tmp\x.pl line 11
To bring home to later readers the full force of what Yoda said in their comment, the simplest solution is to unlearn the notion that you have to try in order to CATCH. You don't:
sub foo()
{
say 1 / 0;
CATCH { default { fail "FAIL" } }
return True;
}
with foo() {
say "done";
}
else
{
say "handled {.exception.message}"
}
correctly displays:
handled FAIL
According to the Failure documentation this seems to be the defined behavior.
Sink (void) context causes a Failure to throw, i.e. turn into a normal exception. The use fatal pragma causes this to happen in all contexts within the pragma's scope. Inside try blocks, use fatal is automatically set, and you can disable it with no fatal.
You can try to use the no fatal pragma.
sub foo() {
try {
no fatal;
say 1 / 0;
CATCH { default { fail "FAIL" } }
}
}
unless foo() {
say "handled"
}
Related
I am using import java.net.http.HttpClient
and my code is as follows:
try {
val response = httpClient.send(httpRequest, BodyHandlers.ofString())
...
when (response.statusCode()) {
200 -> {
result = decodedResponse
} else -> {
val errorResponse = Json.decodeFromString<ErrorObject>(response.body())
throw handleCustomError(errorResponse.error, errorResponse.error_description)
}
}
return result
} catch (ex: Exception) {
throw Exception("Service is unavailable!")
}
my handleCustomError iterates over the different types of status codes 401,403,404 etc and throws user friendly exception. But I dont think that code is ever reached. Instead I see the generic exception thrown by the catch block.
How can I make sure to iterate over the different status code?
I need to verify that a certain call is not made, when a previous method call throws an Exception.
// GIVEN
every { relaxedMock.eats() }.throws(NotHungryException())
// WHEN
sut.live()
// THEN
verify (exactly = 0) { relaxedMock2.sleeps() }
Problem with this code, it fails because of the Exception thrown and not because of the failed verification.
I understand that your WHEN block will always throw an exception.
In that case you have multiple options from my point of view:
Simple plain Kotlin. Wrap the WHEN block with a try-catch block, e.g. like this:
// GIVEN
every { relaxedMock.eats() }.throws(NotHungryException())
// WHEN
var exceptionThrown: Boolean = false
try {
sut.live()
} catch(exception: NotHungryException) {
// Maybe put some assertions on the exception here.
exceptionThrown = true
}
assertTrue(exceptionThrown)
// THEN
verify (exactly = 0) { relaxedMock2.sleeps() }
For a bit nicer code, you can use JUnit5 API's Assertions. assertThrows will expect an exception being thrown by a specific piece of code. It will fail the test, if no exception is thrown. Also it will return the thrown exception, for you to inspect it.
import org.junit.jupiter.api.Assertions
// GIVEN
every { relaxedMock.eats() }.throws(NotHungryException())
// WHEN
val exception = Assertions.assertThrows(NotHungryException::class.java) { sut.live() }
// THEN
verify (exactly = 0) { relaxedMock2.sleeps() }
If you're using Kotest you can use the shouldThrow assertion. Which also allows you to retrieve the thrown exception and validate its type.
import io.kotest.assertions.throwables.shouldThrow
// GIVEN
every { relaxedMock.eats() }.throws(NotHungryException())
// WHEN
val exception = shouldThrow<NotHungryException> { sut.live() }
// THEN
verify (exactly = 0) { relaxedMock2.sleeps() }
I had similar issue and found that my method is not surrounded by try catch. This mean the method will always throw exception.
Test
The unit test to verify the result when the following method is called while stubbing it with predefine Exception
#Test
fun returnSearchError() {
every { searchService.search(query) }.throws(BadSearchException())
val result = searchRepository.search(query)
assertEquals(SearchStates.SearchError, result)
}
Faulty code
fun search(query: String): SearchStates {
val result = searchService.search(query) // No try catch for the thrown exception
return try {
SearchStates.MatchingResult(result)
} catch (badSearchException: BadSearchException) {
SearchStates.SearchError
}
}
Refactored it to
fun search(query: String): SearchStates {
return try {
val result = searchService.search(query)
SearchStates.MatchingResult(result)
} catch (badSearchException: BadSearchException) {
SearchStates.SearchError
}
}
I am trying to use this method:
array<int^,2>^ Function1()
{
return gcnew array<int^,2>{ { 1 }, { 2 }};
}
by typing:
auto x = Function1();
but I get an error:
Exception thrown at 0x73572A55 (clr.dll) in Project1.exe: 0xC0000005: Access violation writing location 0x00000834.
How to solve this problem if I want to keep the returning type?
Thanks!
int is not a reference type, and should not be used with ^.
If you remove the ^ from int^, this code does run:
array<int, 2>^ Function1()
{
return gcnew array<int, 2>{ { 1 }, { 2 } };
}
How to solve this problem if I want to keep the returning type?
This return type is improper. There's no way to represent int^ in C#, and probably not in other .Net languages either. Having a variable of type int^ is a performance hit for each access of the integer, and I believe it's more work for the garbage collector as well.
The proper fix is to change int^ to int everywhere.
Now, that said, I cannot reproduce the error you're getting. Perhaps your error is elsewhere.
array<int^,2>^ Function1()
{
return gcnew array<int^,2>{ { 1 }, { 2 }};
}
int main(array<System::String^>^ args)
{
auto x = Function1();
Debug::WriteLine(x[0,0]);
return 0;
}
Result:
1
Consider the following code:
enum MyErrorType:ErrorType {
case BadTimes
}
var mightHaveAValue: String?
do {
if let value = mightHaveAValue {
// do stuff with value
} else {
throw MyErrorType.BadTimes
}
// do stuff with NSFileManager using mightHaveAValue which might throw
} catch {
// handle error
}
...in which I have a large do/try/catch block. In this instance the error handling will be the same, whether mightHaveAValue is empty or something bad happens with NSFileManager later on. So it makes sense to re-use the error handling code.
Is this the cleanest approach going in Swift2, or is there some way I can automatically throw/catch on unwrapping an optional with no value?
It looks ok, but it's even better with guard let instead of if let because it lets you use the unwrapped value in the main do block instead of having to work inside an if let branch. You can also use several catch branches to handle different error types.
do {
guard let value = mightHaveAValue else {
throw MyErrorType.BadTimes
}
// do stuff with value
} catch let error as MyErrorType {
// handle custom error
} catch let error as NSError {
// handle generic NSError
}
There is no automatic way to handle unwrapping optionals, you have to use one of the many known ways: if let, guard let, nil coalescing, etc.
Maybe just use an extension like this 🤔
extension Optional {
func throwing() throws -> Wrapped {
if let wrapped = self {
return wrapped
} else {
throw NSError("Trying to access non existing value")
}
}
}
How to make the cycle for() to restart or skip when there is an error?
My code moves on web pages, but fails on a non-existent page and returns an error and stops.
I tried try-catch, but I did not understand how to do a re-start or skip.
It should be a simple solution.
function A() {
// do something
}
function B() {
try {
// A();
}
catch(Exception e){
log ( e );
A();
}
finally {
// whatever you want whether theres an exception or not
}
}
I don't know if this might work, but it worths a try.