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
[JENKINS-55945] IllegalStateException trying to get user. #4107
[JENKINS-55945] IllegalStateException trying to get user. #4107
Conversation
This change catches the exception and returns false, invalidating the user session. This behavior is sensible, because if we are unable to validate the user we must assume the session is invalid. Catching the error at this point reportedly helps with some scenarios and shouldn't cause any further harm.
User userFromSession; | ||
try { | ||
userFromSession = User.getById(authentication.getName(), false); | ||
} catch (IllegalStateException ise) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
No-idiomatic abbreviations set a bad example to others. Common names for an exception are e
, x
and ex
. Not a blocker.
Sorry for not submitting this PR on my own! Looks good to me. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why not just every RuntimeException ?
I figured I'd go ahead and get it proposed. I don't want to take away from the work you've done on it, though. You've been able to verify it fixes the issue, whereas no matter what I've tried I can't reproduce it. |
We could, but I wanted to keep this narrowly focused on the specific issue some people have reported. I'm inclined to keep it that way, especially considering the reproduction difficulties and the init sequencing issues that must exist. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
whatever works
Will merge tomorrow if no negative feedback |
try { | ||
userFromSession = User.getById(authentication.getName(), false); | ||
} catch (IllegalStateException ise) { | ||
logger.warn("Encountered IllegalStateException trying to get a user. System init may not have completed yet. Invalidating user session."); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Would it be useful to include the exception in the log message?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I debated that myself. My opinion is that because the handling is so narrow, it would just introduce clutter to include the exception. If we broadened the catch, then we would definitely want to add the exception.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It the issue is understood, a stack trace only makes the log look scarier. It's easy to misread a stack trace as an exception that wasn't handled properly.
On the other hand, the message from the exception could be useful to make sure we caught the correct exception.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@jvz do you consider this comment as resolved?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Oh yeah, good with me.
This change catches the exception and returns false, invalidating the user session. This behavior is sensible, because if we are unable to validate the user we must assume the session is invalid. Catching the error at this point reportedly helps with some scenarios and shouldn't cause any further harm. (cherry picked from commit 8349ceb)
During my testing I have noticed that from time to time when restarting Jenkins, an `IllegalStateException` is thrown. This issue is similar to jenkinsci/jenkins#4107 in fact it is the same issue as we make the same call in our code: https://github.com/jenkinsci/crowd2-plugin/blob/ff4affe98a969c5bcd4de4211656a8db57e841b4/src/main/java/de/theit/jenkins/crowd/CrowdAuthenticationToken.java#L125 Before this patch the log looked like this: ``` Apr 24 08:23:18 Jenkins-McdCore java[516]: INFO: Jenkins stopped Apr 24 08:23:19 Jenkins-McdCore java[516]: Apr 24, 2023 8:23:19 AM hudson.init.impl.InstallUncaughtExceptionHandler handleException Apr 24 08:23:19 Jenkins-McdCore java[516]: WARNING: Caught unhandled exception with ID 2841997a-ee9d-4e6e-a1d0-e36079f288ec Apr 24 08:23:19 Jenkins-McdCore java[516]: java.lang.IllegalStateException: Expected 1 instance of hudson.model.User$AllUsers but got 0 Apr 24 08:23:19 Jenkins-McdCore java[516]: at hudson.ExtensionList.lookupSingleton(ExtensionList.java:454) Apr 24 08:23:19 Jenkins-McdCore java[516]: at hudson.model.User$AllUsers.getInstance(User.java:1098) Apr 24 08:23:19 Jenkins-McdCore java[516]: at hudson.model.User$AllUsers.get(User.java:1116) Apr 24 08:23:19 Jenkins-McdCore java[516]: at hudson.model.User.getOrCreateById(User.java:535) Apr 24 08:23:19 Jenkins-McdCore java[516]: at hudson.model.User.getById(User.java:638) Apr 24 08:23:19 Jenkins-McdCore java[516]: at de.theit.jenkins.crowd.CrowdAuthenticationToken.updateUserInfo(CrowdAuthenticationTok> Apr 24 08:23:19 Jenkins-McdCore java[516]: at de.theit.jenkins.crowd.CrowdRememberMeServices.autoLogin(CrowdRememberMeServices.java> Apr 24 08:23:19 Jenkins-McdCore java[516]: at de.theit.jenkins.crowd.CrowdServletFilter.doFilter(CrowdServletFilter.java:177) ``` The server would still restart but would produce `Oops! A problem occurred while processing the request.`. After the patch: ``` Apr 24 20:13:22 Jenkins-CrowdAAD java[242796]: Apr 24, 2023 8:13:22 PM hudson.lifecycle.Lifecycle onStatusUpdate Apr 24 20:13:22 Jenkins-CrowdAAD java[242796]: INFO: Jenkins stopped Apr 24 20:13:23 Jenkins-CrowdAAD java[242796]: Apr 24, 2023 8:13:23 PM de.theit.jenkins.crowd.CrowdRememberMeServices autoLogin Apr 24 20:13:23 Jenkins-CrowdAAD java[242796]: WARNING: Encountered IllegalStateException. System init may not have completed yet. Apr 24 20:13:23 Jenkins-CrowdAAD java[242796]: Apr 24, 2023 8:13:23 PM hudson.security.HttpSessionContextIntegrationFilter2 hasInvalidSessionSeed Apr 24 20:13:23 Jenkins-CrowdAAD java[242796]: WARNING: Encountered IllegalStateException trying to get a user. System init may not have completed yet. Invalidating user session. Apr 24 20:13:25 Jenkins-CrowdAAD java[242796]: Running from: /opt/jenkins_home/jenkins.war Apr 24 20:13:25 Jenkins-CrowdAAD java[242796]: webroot: /opt/jenkins_home/war Apr 24 20:13:25 Jenkins-CrowdAAD java[242796]: Apr 24, 2023 8:13:25 PM winstone.Logger logInternal Apr 24 20:13:25 Jenkins-CrowdAAD java[242796]: INFO: Beginning extraction from war file ```
This change catches the exception and returns false, invalidating the user session. This behavior is sensible, because if we are unable to validate the user we must assume the session is invalid.
Catching the error at this point reportedly helps with some scenarios and shouldn't cause any further harm.
This error shows up only in some scenarios or environments and I have been unable to reproduce it myself despite hours spent trying. This change is based upon one proposed and tested on the Jira ticket by Pavel Roskin. Without the change, Pavel reports encountering the error reliably. With the change, it didn't manifest.
There is a deeper problem here, as the exception is correctly thrown because of an illegal state. There must be one instance of AllUsers once the init sequence is complete and Jenkins shouldn't respond if it isn't. I encountered a similar error once, but in that case it originated in
Jenkins.get()
. It would be nice to figure out what to do about the illegal state, but I haven't been able to dig up any clues. I figure that this minor change will at least address the situation seen by some users.As I haven't been able to reproduce the problem or determine any cause, I haven't been able to readily provide any autotests for the illegal state. I could try inserting some mocks, but those are notoriously clumsy and difficult, particularly for these sorts of things.
See JENKINS-55945.
Proposed changelog entries
Submitter checklist
* Use the
Internal:
prefix if the change has no user-visible impact (API, test frameworks, etc.)