Groovy end exception different from exception thrown - exception

I am running into an extremely strange behavior in Groovy. When I throw an exception from a closure in a Script, the end exception that was thrown was different.
Here are the code and the details:
public class TestDelegate {
def method(Closure closure) {
closure.setResolveStrategy(Closure.DELEGATE_FIRST);
closure.delegate = this;
closure.call();
}
public static void main(String[] args) {
// Make Script from File
File dslFile = new File("src/Script.dsl");
GroovyShell shell = new GroovyShell();
Script dslScript = shell.parse(dslFile);
TestDelegate myDelegate = new TestDelegate();
dslScript.metaClass.methodMissing = {
// will run method(closure)
String name, arguments ->
myDelegate.invokeMethod(name, arguments);
}
dslScript.metaClass.propertyMissing = {
String name ->
println "Will throw error now!"
throw new MyOwnException("errrrror");
}
dslScript.run();
}
}
class MyOwnException extends Exception {
public MyOwnException(String message) {
super(message);
}
}
Script.dsl:
method {
println a;
}
So the plan is that when I run the main() method in TestDelegate, it will run the DSL script, which calls for the method method(). Not finding it in the script, it will invoke methodMissing, which then invokes method() from myDelegate, which in turns invoke the closure, setting the delegate to the testDelegate. So far, so good. Then the closure is supposed to try printing out "a", which is not defined and will thus set off propertyMissing, which will will throw MyOwnException.
When I run the code, however, I get the following output:
Will throw error now!
Exception in thread "main" groovy.lang.MissingPropertyException: No such property: a for class: TestDelegate
Now, it must have reached that catch block, since it printed "Will throw error now!" It must have thrown MyOwnException too! But somewhere along the lines, MyOwnException was converted to MissingPropertyException, and I have no idea why. Does anyone have any idea?
P.S. if I remove closure.setResolveStrategy(Closure.DELEGATE_FIRST) from TestDelegate#method(), the code acts as expected and throws MyOwnException. But I really need the setResolveStrategy(Closure.DELEGATE_FIRST) for my DSL project. And I would prefer to know the root cause of this rather than just removing a line or two and see that it works without understanding why.

I think this is what essentially happens: With a delegate-first resolve strategy, the Groovy runtime first tries to access property a on myDelegate, which results in a MissingPropertyException because no such property exists. Then it tries propertyMissing, which causes a MyOwnException to be thrown. Eventually the runtime gives up and rethrows the first exception encountered (a design decision), which happens to be the MissingPropertyException.
With an owner-first resolve strategy, propertyMissing is consulted first, and hence MyOwnException is eventually rethrown.
Looking at the stack trace and source code underneath should provide more evidence.

Related

C++Winrt how to throw and handle exception without terminating program

I have following code
IAsyncOperation<bool> trythiswork()
{
bool contentFound{ false };
try
{
auto result = co_await someAsyncFunc();
winrt::check_bool(result)
if (result)
{
contentFound = true;
}
}
catch (...)
{
LOG_CAUGHT_EXCEPTION();
}
co_return contentFound;
}
When the result is false, it fails and throws but catch goes to fail fast and program terminates. How does log function terminate the program? Isn't it supposed to only log the exception? I assumed that I am handling this exception so program won't crash but it is crashing.
So how to throw and catch so that program does not terminate? I do want to throw. And also catch and preferably log the exception as well.
Thanks
The issue can be reproduced using the following code:
IAsyncOperation<bool> someAsyncFunc() { co_return false; }
IAsyncOperation<bool> trythiswork()
{
auto contentFound { false };
try
{
auto result = co_await someAsyncFunc();
winrt::check_bool(result);
// throw std::bad_alloc {};
contentFound = true;
}
catch (...)
{
LOG_CAUGHT_EXCEPTION();
}
co_return contentFound;
}
int main()
{
init_apartment();
auto result = trythiswork().get();
}
As it turns out, everything works as advertised, even if not as intended. When running the code with a debugger attached you will see the following debug output:
The exception %s (0x [trythiswork]
Not very helpful, but it shows that logging itself works. This is followed up by something like
FailFast(1) tid(b230) 8007023E {Application Error}
causing the process to terminate. The WIL only recognizes exceptions of type std::exception, wil::ResultException, and Platform::Exception^. When it handles an unrecognized exception type it will terminate the process by default. This can be verified by commenting out the call to check_bool and instead throwing a standard exception (such as std::bad_alloc). This produces a program that will log exception details, but continue to execute.
The behavior can be customized by registering a callback for custom exception types, giving clients control over translating between custom exception types and HRESULT values. This is useful in cases where WIL needs to interoperate with external library code that uses its own exception types.
For C++/WinRT exception types (based on hresult_error) the WIL already provides error handling helpers that can be enabled (see Integrating with C++/WinRT). To opt into this all you need to do is to #include <wil/cppwinrt.h> before any C++/WinRT headers. When using precompiled headers that's where the #include directive should go.
With that change, the program now works as desired: It logs exception information for exceptions that originate from C++/WinRT, and continues to execute after the exception has been handled.

How to catch the original Exception, when using WebServices?

After searching for days now and reading pretty much everything related to that, I'm finally posting my question here, since I couldn't find a solution for my specific problem.
I want my REST WebServices to return the original Exception, that has been thrown or at least the correct StackTrace. To test this, I'm using JUnit integrationtests and Wildfly 13 as app-server. After researching I found 2 possible solutions.
1.Using Exception Mappers
While this magical thing catches all of my Exceptions and allows me to return a Response, I've noticed that my StackTrace is changed if I use it like in the example. For example, "com.test.TestClass" is turned into "null.thread" or "null.interceptor". It seems like somehow the exception is changed on the way and the paths to the class are lost or censored, but I can't make sense of it.
Also I couldn't find any restrictions for the Response.entity, be it size, datatype or security.
As far as I understand, you can catch the ExceptionMapper Response OR a WebApplicationException, which contains the response. In my case, the response in the WebApplicationException contains all the relevant data except the (correct) StackTrace.
2.Using WebApplicationException
Another Solution would be to simply throw WebApplicationException instead of ECEException and not using a mapper. If I do that and catch it, the Exception is empty though. It doesn't contain any of the data set, it's always 500 - InternalServerError (I guess, Wildfly couldn't handle it then and threw an exception itself).
Or is it not supposed to be catched/thrown like that? Do I need to convert it to JSon or can I expect it to simply work out of the box with my annotations in the WebServiceInterface and the Response MediaType? Does it even make sense to put a full Response within a WebApplicationException? I mean, both contain fields for the ErrorCode, which seems redundand, even though there is a constructor for that approach.
Long story short:
What's the best approach to catch all possible exceptions and retrieve the full stack trace? Reading this post, I guess catching all "Exception"s is fine and they are always returned as WebApplicationExceptions, but the stack trace is still gone/malformed... your thoughts?
**JUnitTest**
#Test
public void testCreateTask_ClusterInvalid() throws IOException {
final RPETask taskToCreate = new RPETask();;
try
{
final long tid = taskManagerWebService.createTask(taskToCreate);
}
catch (WebApplicationException e) //Responses are ALWAYS catched as WebApplicationException
{
Response response = e.getResponse();
String emString = response.readEntity(String.class);
Gson gson = new Gson();
ECEWebErrorMessage errorMessage = gson.fromJson(emString, ECEWebErrorMessage.class);
errorMessage.displayErrorInformationOnConsole();
}
}
**WebServiceInterface**
#POST
#Path(URI_CREATE_TASK)
#Consumes(WebServiceNames.JSON)
#Produces(WebServiceNames.JSON)
long createTask(final RPETask task) throws ECEException;
**WebService**
#Override
public long createTask(final RPETask task) throws ECEException {
if (LOGGER.isTraceEnabled()) {
LOGGER.trace("createTask(" + task + ")");
}
return taskManager.createTask(task);
}
**ManagerBeanInterface**
long createTask(RPETask task) throws ECEException;
**ManagerBean**
#Override
public long createTask(final RPETask task) throws ECEException {
final ClusterEngineBean cluster = find(ClusterEngineBean.class, task.getCluster());
if (cluster == null) {
throw new ECEObjectNotFoundException(ClusterEngineBean.class, task.getCluster());
}
}
**ExceptionMapper**
#Provider
public class GenericWebExceptionMapper implements ExceptionMapper<Exception> {
final Log logger = LogFactory.getLog(getClass());
#Override
public Response toResponse(Exception ex) {
//At this point, the Exception is fully available -> Sending it as Response breaks it!
logger.error("GenericWebExceptionMapper -> toResponse(Throwable ex)", ex);
ECEWebErrorMessage errorMessage = new ECEWebErrorMessage(500,
ex.getMessage(),
ex.getClass().getCanonicalName(),
ex.getStackTrace());
return Response.status(Status.INTERNAL_SERVER_ERROR)
.entity(errorMessage)
.type(MediaType.APPLICATION_JSON)
.build();
}
}
After more research I've finally found a solution for myself.
Why is the StackTrace gone/malformed?
It's for security reasons. Wildfly automatically detects outgoing StackTraces and censors them, using interceptors. Im not sure if you can do anything about that, but I guess you shouldn't do that anyway.
What is the best approach?
Using Exception Mappers worked for me. Instead of catching them as WebApplicationException, you can always expect a response with the appropriote error code and handle them that way. For example error code 200 = OK, do this... error code 404 = NOTFOUND, do that...I that case your WebServices should always return Responses and contain the object you want to retreive in the entity field of the Response.
Feel free to add additional information to this solution.

How to know exception occurred within grails transaction?

I have a service method which does some operation inside a transaction.
public User method1() {
// some code...
Vehicle.withTransaction { status ->
// some collection loop
// some other delete
vehicle.delete(failOnError:true)
}
if (checkSomething outside transaction) {
return throw some user defined exception
}
return user
}
If there is a runtime exception we dont have to catch that exception and the transaction will be rolled back automatically. But how to determine that transaction rolled back due to some exception and I want to throw some user friendly error message. delete() call also wont return anything.
If I add try/catch block inside the transaction by catching the Exception (super class) it is not getting into that exception block. But i was expecting it to go into that block and throw user friendly exception.
EDIT 1: Is it a good idea to add try/catch arround withTransaction
Any idea how to solver this?? Thanks in advance.
If I understand you question correctly, you want to know how to catch an exception, determine what the exception is, and return a message to the user. There are a few ways to do this. I will show you how I do it.
Before I get to the code there are a few things I might suggest. First, you don't need to explicitly declare the transaction in a service (I'm using v2.2.5). Services are transactional by default (not a big deal).
Second, the transaction will automatically roll back if any exception occurs while executing the service method.
Third, I would recommend removing failOnError:true from save() (I don't think it works on delete()... I may be wrong?). I find it is easier to run validate() or save() in the service then return the model instance to the controller where the objects errors can be used in a flash message.
The following is a sample of how I like to handle exceptions and saves using a service method and try/catch in the controller:
class FooService {
def saveFoo(Foo fooInstance) {
return fooInstance.save()
}
def anotherSaveFoo(Foo fooInstance) {
if(fooInstance.validate()){
fooInstance.save()
}else{
do something else or
throw new CustomException()
}
return fooInstance
}
}
class FooController {
def save = {
def newFoo = new Foo(params)
try{
returnedFoo = fooService.saveFoo(newFoo)
}catch(CustomException | Exception e){
flash.warning = [message(code: 'foo.validation.error.message',
args: [org.apache.commons.lang.exception.ExceptionUtils.getRootCauseMessage(e)],
default: "The foo changes did not pass validation.<br/>{0}")]
redirect('to where ever you need to go')
return
}
if(returnedFoo.hasErrors()){
def fooErrors = returnedFoo.errors.getAllErrors()
flash.warning = [message(code: 'foo.validation.error.message',
args: [fooErrors],
default: "The foo changes did not pass validation.<br/>${fooErrors}")]
redirect('to where ever you need to go')
return
}else {
flash.success = [message(code: 'foo.saved.successfully.message',
default: "The foo was saved successfully")]
redirect('to where ever you need to go')
}
}
}
Hope this helps, or gets some other input from more experienced Grails developers.
Here are a few other ways I've found to get exception info to pass along to your user:
request.exception.cause
request.exception.cause.message
response.status
A few links to other relevant questions that may help:
Exception handling in Grails controllers
Exception handling in Grails controllers with ExceptionMapper in Grails 2.2.4 best practice
https://commons.apache.org/proper/commons-lang/javadocs/api-2.6/org/apache/commons/lang/exception/ExceptionUtils.html

How can I wait on tasks without throwing TaskCanceledExceptions?

I have a method that creates some Tasks, and then waits on them with WaitAll before returning. The problem is, if those tasks got canceled, then WaitAll throws an AggregateException containing lots of TaskCanceledExceptions.
That means that WaitAll will throw exceptions in two different circumstances:
Exceptions that indicate a genuine error. These mean that there was a condition we didn't know how to handle; they need to propagate as unhandled exceptions, until they eventually terminate the process.
Exceptions that indicate that the user clicked a Cancel button. These mean that the task was canceled and cleaned up, and the program should continue running normally.
The latter fits squarely into the definition of a vexing exception: it's an exception thrown in a completely non-exceptional circumstance, so I have to catch it in order to resume normal control flow. Fortunately it's easy to catch, right? Just add catch (AggregateException) and -- oh wait, that's the same type that gets thrown when there's a fatal error.
I do need to wait for the tasks to finish running before I return (I need to know that they're no longer using their database connections, file handles, or anything else), so I do need the WaitAll or something similar. And if any of the tasks faulted, I do want those exceptions to propagate as unhandled exceptions. I just don't want exceptions for cancel.
How can I prevent WaitAll from throwing exceptions for canceled tasks?
The AggregateException provides a Handle method that can be used for these situations. If for example you want to ignore TaskCanceledException you can do:
var all = new AggregateException(
new NullReferenceException(),
new TaskCanceledException(),
new TaskCanceledException(),
new InvalidOperationException(),
new TaskCanceledException());
try
{
throw all;
}
catch (AggregateException errors)
{
errors.Handle(e => e is TaskCanceledException);
}
If all the exceptions are of type TaskCanceledException, the Handle method will not throw any exception; otherwise a new AggregateException containing only the unhandled exceptions will be thrown.
Based on João Angelo's suggestion, here goes a Task class extension
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
namespace MySharedLibrary.Extensions
{
public static class TaskExtensions
{
// This code is based João Angelo's stackoverflow suggestion https://stackoverflow.com/a/8681687/378115
// Use this when a CancellationTokenSource is used
public static void SafeWait(this Task TargetTask, CancellationTokenSource TargetTaskCancellationTokenSource)
{
if (TargetTaskCancellationTokenSource.IsCancellationRequested == false)
{
TargetTaskCancellationTokenSource.Cancel();
}
SafeWait(TargetTask);
}
// Use this when no CancellationTokenSource is used
public static void SafeWait(this Task TargetTask)
{
try
{
if (TargetTask.IsCanceled == false)
{
TargetTask.Wait();
}
}
catch (AggregateException errors)
{
errors.Handle(e => e is TaskCanceledException);
}
}
}
}

How to test for additional properties of expected Exceptions using ScalaTest

I'm using ScalaTest for testing some Scala code.
I currently testing for expected exceptions with code like this
import org.scalatest._
import org.scalatest.matchers.ShouldMatchers
class ImageComparisonTest extends FeatureSpec with ShouldMatchers{
feature("A test can throw an exception") {
scenario("when an exception is throw this is expected"){
evaluating { throw new Exception("message") } should produce [Exception]
}
}
}
But I would like to add additional check on the exception, e.g. I would like to check that the exceptions message contains a certain String.
Is there a 'clean' way to do this? Or do I have to use a try catch block?
I found a solution
val exception = intercept[SomeException]{ ... code that throws SomeException ... }
// you can add more assertions based on exception here
You can do the same sort of thing with the evaluating ... should produce syntax, because like intercept, it returns the caught exception:
val exception =
evaluating { throw new Exception("message") } should produce [Exception]
Then inspect the exception.
If you need to further inspect an expected exception, you can capture it using this syntax:
val thrown = the [SomeException] thrownBy { /* Code that throws SomeException */ }
This expression returns the caught exception so that you can inspect it further:
thrown.getMessage should equal ("Some message")
you can also capture and inspect an expected exception in one statement, like this:
the [SomeException] thrownBy {
// Code that throws SomeException
} should have message "Some message"