Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix issue 26317 #26343

Closed
wants to merge 1 commit into from
Closed

fix issue 26317 #26343

wants to merge 1 commit into from

Conversation

dongbaibai
Copy link

fix 【@ExceptionHandler methods not invokable if matched on exception's cause level > 1 】
the cause is:
ExceptionHandlerMethodResolver#resolveMethodByThrowable Find a Method to handle the given Throwable
only find Exception.cause twice

it will not affect the order of looking up for exception handler methods (1.local exception handler method,2.global exception handler method)
it only affects ExceptionHandlerMethodResolver.resolveMethod that what we what

hope to adopt

@pivotal-issuemaster
Copy link

@dongbaibai Please sign the Contributor License Agreement!

Click here to manually synchronize the status of this Pull Request.

See the FAQ for frequently asked questions.

@spring-projects-issues spring-projects-issues added the status: waiting-for-triage An issue we've not yet triaged or decided on label Jan 4, 2021
@rod2j
Copy link

rod2j commented Jan 4, 2021

Hi @dongbaibai ,

Did you actually check that your change fixed the issue I related ?

Because watching at your commit, you only changed the implementation of ExceptionHandlerMethodResolver#resolveMethodByThrowable:

  • you replaced the use of recursivity with a nested while loop
  • but there's no change in the outcome

So that will obviously not change anything in the way the resolved method is actually called and cannot fix the issue.

Copy link
Contributor

@quaff quaff left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hi @dongbaibai ,

Did you actually check that your change fixed the issue I related ?

Because watching at your commit, you only changed the implementation of ExceptionHandlerMethodResolver#resolveMethodByThrowable:

  • you replaced the use of recursivity with a nested while loop
  • but there's no change in the outcome

So that will obviously not change anything in the way the resolved method is actually called and cannot fix the issue.

Agree.

method = resolveMethodByThrowable(cause);
}
Throwable cause = exception.getCause();
while (method == null && cause != null) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Possible endless loop here, depth should be limited, and cause should not be exception itself.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It can't be infinite loop

@dongbaibai
Copy link
Author

dongbaibai commented Jan 5, 2021

hi @rod2j
here is original process:

1.find method by exception type first
2.if method is null and the exception has cause
3.then find method by cause type

so ExceptionHandlerMethodResolver#resolveMethodByThrowable can not find a method by exception type that was nested more than one exception

just like this : new RuntimeException(new Exception(new IllegalArgumentException("ExceptionHandler will be resolved but cannot be invoked")));

so i think what need to do is change the logic that assigns the exception type only

@rstoyanchev
Copy link
Contributor

I don't think this addresses #26317 which fails not because the method is not matched, but because the method arguments cannot be properly matched. I'm closing for now but we can re-open again if necessary. @dongbaibai have you confirmed the fix in any way? For example with the sample attached to #26317. There are no tests either to confirm the fix.

@rstoyanchev rstoyanchev closed this Jan 7, 2021
@rstoyanchev rstoyanchev added status: invalid An issue that we don't feel is valid and removed status: waiting-for-triage An issue we've not yet triaged or decided on labels Jan 7, 2021
@dongbaibai
Copy link
Author

I don't think this addresses #26317 which fails not because the method is not matched, but because the method arguments cannot be properly matched. I'm closing for now but we can re-open again if necessary. @dongbaibai have you confirmed the fix in any way? For example with the sample attached to #26317. There are no tests either to confirm the fix.

i will attach some sample later

@rstoyanchev
Copy link
Contributor

rstoyanchev commented Jan 8, 2021

There is no need to attach a sample. There is a sample under #26317 and that should be used to confirm any potential fix.

@dongbaibai
Copy link
Author

dongbaibai commented Jan 11, 2021

/**
 * For convenience, I've focused all of my code on this one class
 */
@SpringBootApplication
public class Application {

    public static void main(String[] args) {
        SpringApplication.run(Application.class);
    }

    @RestController
    public static class TestController {
        @GetMapping("/ExceptionHandler")
        public String hi() {
            throw new RuntimeException(new Exception(new IllegalArgumentException("error message")));
        }
    }

    /**
     * wrapper @ExceptionHandler method with ExceptionHandlerBean
     * to simulate to find an @ExceptionHandler method for the given exception
     * on ExceptionHandlerExceptionResolver.exceptionHandlerAdviceCache
     * not on the controller class itself
     */
    @ResponseBody
    @ControllerAdvice
    public static class ExceptionHandlerBean {

        @ExceptionHandler(value = {IllegalArgumentException.class})
        public String error() {
            return "error";
        }

    }
}

I will prove from two ways

  1. init exceptionHandler, ExceptionHandlerExceptionResolver#initExceptionHandlerAdviceCache. The picture of exceptionHandler is below. We saw IllegalArgumentException mapping Application$ExceptionHandlerBean.error. So the init exceptionHandler is alright.
  2. Find a method to handle the given Exception, ExceptionHandlerMethodResolver#resolveMethod. The picture of exception type is below.

image

image

image

image

@quaff
Copy link
Contributor

quaff commented Jan 11, 2021

@dongbaibai You should write unit test which failed before you commit and passed now, instead of pasting lots of code.

@sbrannen
Copy link
Member

@dongbaibai, I've edited your latest comment to improve the formatting. You might want to check out this Mastering Markdown guide for future reference.

Furthermore, as mentioned previously in #26343 (comment), when submitting a PR that claims to fix a bug, the PR must contain one or more JUnit-based tests that demonstrate the bug (by failing before the fix) and the fix (by passing after the fix).

Providing a sample Spring Boot application that demonstrates the problem is not sufficient since it cannot be incorporated into the Spring Framework test suite.

This PR will remain closed until tests are provided that confirm the bug and the fix.

@pivotal-cla
Copy link

@dongbaibai Please sign the Contributor License Agreement!

Click here to manually synchronize the status of this Pull Request.

See the FAQ for frequently asked questions.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
status: invalid An issue that we don't feel is valid
Projects
None yet
Development

Successfully merging this pull request may close these issues.

8 participants