I have a spock test, which calls some service:
when:
def x = service.call()
then:
!x
Inside service I have:
def call() {
try {
doCall() // method, which throws an exception
} catch (e) {
false
}
}
So I expect method to return false and test to pass. However, test invocation from IDE prints stacktrace of the exception, though it is catched.
Purpose of the test is not to know whether exception was thrown, but just assert returned result is false, so I don't want to use Specification.thrown
First of all - check what specific exception gets thrown and gets outside the try-catch block. You have to be aware that following code in Groovy:
try {
// do something
} catch (e) {
// do something with exception
}
is an equivalent of:
try {
// do something
} catch (Exception e) {
// do something with exception
}
It means that java.lang.Throwable and all its children classes (except java.lang.Exception) are not caught inside your try catch. For instance:
def call() {
try {
throw new Error('Something wrong happened')
} catch (e) {
false
}
}
This exception won't get caught by try-catch and you will see something like this in the console log:
java.lang.Error: Something wrong happened
at com.github.wololock.micronaut.TestSpec$Service.call(TestSpec.groovy:22)
at com.github.wololock.micronaut.TestSpec.test(TestSpec.groovy:13)
It happens, because java.lang.Error extends java.lang.Throwable and it is not a child class of java.lang.Exception.
If you want to catch all possible exceptions that may happened to your code you would have to use Throwable inside the catch block, something like this:
def call() {
try {
throw new Error('Something wrong happened')
} catch (Throwable e) {
false
}
}
Related
Android app, Having a function calling another function, that function may throw
static string SOME_DEFINE_1 = "some_define_1";
......
void myFunc() {
try {
HashMap<String, String> data = new HashMap<>();
data.put("key_1", SOME_DEFINE_1);
otherObject.func(data);
} catch (Throwable ex){
Log.e(TAG, "+++ exception from otherObject.func(), "+ ex.toString());
// do something
anotherFunc();
}
}
How to test the catch block is called when unit testing the myFunc?
It isn't clear in your example where otherObject comes from, but in general, to test the exception handling blocks you need code that will throw the exception. In this example, one way may be to mock the otherObject and then use thenThrow to cause it to throw an exception when the func(data) method is called. You could use a spy of the class you are testing and stub the anotherFunc method so you can replace it with something else and then verify if it was invoked for the conditions you expect to throw the exception.
These articles show the general approach:
https://www.baeldung.com/mockito-spy - (number 4)
https://www.baeldung.com/mockito-exceptions
So in a pseudo-code example:
// arrange
myClassUnderTest = spy(TheClassUnderTest);
otherObject = mock(OtherObject);
doNothing().when(myClassUnderTest).anotherFunc();
doThrow(new RuntimeException("simulated exception")).when(otherObject).func(any());
// act
myClassUnderTest.myFunc();
// assert
verify(myClassUnderTest , times(1)).anotherFunc();
In the below code:
def build(arg1, arg2, arg3, arg4, arg5){
try{
executeBuildCommand(commandString, component)
}
}catch(Exception e){
print ' build() method raised exception'
print "Error cause: ${e}"
error('Build stage - failed')
}
}
def executeBuildCommand(arg1, arg2){
try{
// BUILD_FULL = sh('build the code')
if(BUILD_FULL == true){
def data = new URL(${BUILD_URL}).getText()
}
}catch(Exception e){
throw e
}
}
I understand that "${BUILD_URL}" interpolates in runtime
But catch block in build() method, does not catch exception thrown on line(def data = new URL(${BUILD_URL}).getText())
instead I receive exception stack
java.lang.NoSuchMethodError: No such DSL method '$' found among steps [ArtifactoryGradleBuild, MavenDescriptorStep, acceptGitLabMR,
addGitLabMRComment, addInteractivePromotion, ansiColor, archive, artifactoryDistributeBuild,... ] or
globals [Artifactory, LastChanges, currentBuild, docker, env, params, pipeline, scm]
at org.jenkinsci.plugins.workflow.cps.DSL.invokeMethod(DSL.java:201)
at org.jenkinsci.plugins.workflow.cps.CpsScript.invokeMethod(CpsScript.java:122)
How to handle exceptions?
There are at least two problems in your executeBuildCommand:
new URL(${BUILD_URL}) means that you are trying to call some method $ which has a closure as the only argument. You certainly wanted it to look like new URL("${BUILD_URL}") in order to interpolate BUILD_URL. Or why not use just new URL(BUILD_URL)?
As a result of point 1, you get java.lang.NoSuchMethodError for $. But you try to catch Exception which is not a superclass of NoSuchMethodError. The latter has java.lang.Error as a superclass. If you had tried catching an Error you'd have seen your messages
Probably a stupid question... but here goes anyway...
I would like to know if the quartz.net job will be active to run on the next iteration though there is an exception( which is handled) in the current iteration. Can anyone please explain me if my understanding is correct?
public void Execute(IJobExecutionContext context)
{
_logProvider.Info("Started..");
try
{
_service.Calculate();
}
catch (Exception ex)
{
_logProvider.Error("Error " + ex);
}
}
Thanks
The simple answer is: yes, it will execute on next iteration.
Actually this is related to general .NET exception handling, rather then quartz.net behaviour:
if you have function that catches any exceptions - exceptions will not be visible outside of that function. In other words, code like
public void SomeMethod()
{
try
{
//some logic that can generate exception
}
catch (Exception ex)
{
}
}
is the same as
public void SomeMethod()
{
//some logic that NEVER generates the exception
}
In scope of quartz.net:
The only type of exception that you are allowed to throw from the execute method is JobExecutionException.
otherwise you will have unhandled exception in AppDomain. You can find more in Quartz.net Job unhandled exception behaviour SO question
I have been reading about exceptions for the past couple of hours and have a basic understanding. However the book I'am reading hasn't got the best examples when it comes to showcasing the coding aspects. I know that if I have code that could fail I wrap it in a try block and the catch the exceptions specifically i.e FormatException etc.
However the confusing part is when it comes to call stack were for e.g Method A calls Method B and Method B calls method C etc.
For example a exception occurs in Method c but it doesn't have a catch handler so it propagates back to the calling method so on and so fourth until one way or another the exception is handled.
What I was wondering is does execution continue in the method that caused the error or does execution continue in the method that handles the error.
Any basic examples would be great.
I won't repeat what the other answers have already said, but one other thing to point out is that any finally blocks will be executed after the catch statement happens, but before the exception is re-thrown down the stack. In other words, finally blocks are executed from the top of the stack, down.
For example:
static void Main(string[] args)
{
try
{
Crash(); // Causes a crash
}
catch
{
Console.WriteLine("Third"); // Exception re-thrown, this runs third
}
finally
{
Console.WriteLine("Fourth"); // Run last
}
// Code will continue here when all is done
}
static void Crash()
{
try
{
throw new ApplicationException();
}
catch
{
Console.WriteLine("First"); // This runs first
throw; // Re-throw exception
}
finally
{
Console.WriteLine("Second"); // This gets run second
}
Console.WriteLine("This will never execute..");
}
Will output First, then Second, Third, Fourth.
What I was wondering is does execution continue in the method that caused the error or does execution continue in the method that handles the error.
Second one is correct.For example in your B method if there is exception thrown and not handled,it goes to the caller method for example A,and if A handles that exception program will continue execution from that method.Consider this example:
private static void Main(string[] args)
{
A();
}
static void A()
{
try
{
B();
}
catch (Exception ex)
{
Console.WriteLine("Exception is thrown by {0} method and handled in A method.",ex.TargetSite);
}
Console.WriteLine("We are still in A method...");
}
static void B()
{
throw new Exception();
Console.WriteLine("We can't see this...");
}
This will produce the output:
// Exception is thrown by B() method and handled in A method.
// We are still in A method...
I'm using GPars' fork/join. When I throw an exception after calling forkOffChild, it gets buried.
For example:
def myRecursiveClosure = { boolean top ->
try {
if (!top) {
throw new RuntimeException('child had a problem')
} else {
forkOffChild(false)
}
} catch (Exception exc) {
println 'Exception handled internally'
throw exc
}
}
try {
GParsPool.withPool {
GParsPool.runForkJoin(true, myRecursiveClosure)
}
} catch (Exception exc) {
println 'Exception handled externally'
throw exc
}
Here, I set a flag so I know the closure has been called recursively. Then, I throw an exception, which gets caught 'internally', but the re-throw is never caught 'externally'. So I am not aware that the forked child failed.
I tried the exception handler also, but it doesn't seem to get called either.
Is this expected behavior, or am I doing something wrong? Are there any strategies to help with this? I can't have the child silently fail.
Thanks!
The important piece here is that forkOffChild() doesn't wait for the child to run. It merely schedules it for execution. So you cannot expect the forkOffChild() method to propagate exceptions from the child, since they are likely to happen long after the parent has returned from the forkOffChild() method.
Typically, however, a parent is interested in the outcome of the child computations, so it at some point after forking off collects the results using the getChildrenResults() method. This gives you back a list of calculated values or re-throws potential exceptions.
This snippet shows a minimal change to get the expected behavior:
try {
if (!top) {
throw new RuntimeException('child had a problem')
} else {
forkOffChild(false)
println childrenResults
}
} catch (Exception exc) {
println 'Exception handled internally'
throw exc
}