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

Deleting used build config results in non-editable webhook #242

Open
matt-richardson opened this issue Apr 18, 2024 · 9 comments
Open

Deleting used build config results in non-editable webhook #242

matt-richardson opened this issue Apr 18, 2024 · 9 comments
Labels

Comments

@matt-richardson
Copy link
Contributor

Expected Behavior

A webhook configured to point to deleted build config should be able to be loaded.

Current Behavior

We get an error
image

Steps to Reproduce (for bugs)

  1. Create a teamcity project Project1
  2. Create 2 build configs within that project BuildConfigA and BuildConfigB
  3. Create a webhook in Project1, that only triggers on BuildConfigB
    1. Viewing the project-config.xml shows that the id is stored in the build-types
      image
  4. Delete BuildConfigB
  5. Go to the root webhook page (/admin/admin.html?item=tcWebHooks)
  6. Click on the "There a n WebHooks configured in this TeamCity Server" link
  7. Click on Edit project Webhooks for Project1
  8. Click on edit for the webhook created in step 3
    -> get failure popup An unexpected error occured. Please see your browser's javascript console.

Console log has:

<div class="errorPage">
  <h1 class="errorTitle">Unexpected Error</h1>
  <p>
    This was not supposed to happen.
    Please provide the error details to your TeamCity server maintainer.<br/>
    If you maintain this TeamCity installation and the request seems legit please
    <a href="https://www.jetbrains.com/help/teamcity/feedback.html">report</a> this error to JetBrains.
 </p>
  <div class="errorMessage">
    Error: webhook.teamcity.exception.NonExistantProjectException: No build type found with matching internal Id:bt62
  </div>
  <br/>
  <div>
    Server time: 2024-04-19 07:07:02
  </div>
<div>
  TeamCity: 2024.03 (build 156166)
</div>

with an stack trace of:

Trace: webhook.teamcity.exception.NonExistantProjectException: No build type found with matching internal Id:bt62
    at webhook.teamcity.ProjectAndBuildTypeResolverImpl.getExternalBuildTypeId(ProjectAndBuildTypeResolverImpl.java:51)
    at webhook.teamcity.ProjectAndBuildTypeResolverImpl.getExternalBuildTypeIds(ProjectAndBuildTypeResolverImpl.java:71)
    at webhook.teamcity.json.WebHookConfigurationJson.fromWebHookConfig(WebHookConfigurationJson.java:83)
    at webhook.teamcity.extension.WebHookEditController.doHandle(WebHookEditController.java:74)
    at jetbrains.buildServer.controllers.BaseController.handleRequestInternal(BaseController.java:113)
    at org.springframework.web.servlet.mvc.AbstractController.handleRequest(AbstractController.java:177)
    at jetbrains.buildServer.controllers.BaseController.handleRequest(BaseController.java:92)
    at org.springframework.web.servlet.mvc.SimpleControllerHandlerAdapter.handle(SimpleControllerHandlerAdapter.java:51)
    at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:1072)
    at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:965)
    at jetbrains.buildServer.maintenance.WebDispatcherServlet.doService(WebDispatcherServlet.java:17)
    at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:1006)
    at org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:898)
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:529)
    at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:883)
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:623)
    at jetbrains.buildServer.maintenance.TeamCityDispatcherServlet.processedByMainServlet(TeamCityDispatcherServlet.java:20)
    at jetbrains.buildServer.maintenance.TeamCityDispatcherServlet.service(TeamCityDispatcherServlet.java:76)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:210)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:154)
    at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:51)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:179)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:154)
    at jetbrains.buildServer.https.HttpsRedirectFilter.doFilter(HttpsRedirectFilter.java:32)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:179)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:154)
    at jetbrains.buildServer.web.DisableSessionIdFromUrlFilter.doFilter(DisableSessionIdFromUrlFilter.java:8)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:179)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:154)
    at jetbrains.buildServer.web.UserIdProviderFilter.doFilter(UserIdProviderFilter.java:8)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:179)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:154)
    at jetbrains.buildServer.web.BannedIPsFilter.doFilter(BannedIPsFilter.java:5)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:179)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:154)
    at jetbrains.buildServer.web.NodeInfoHeaderFilter.doFilter(NodeInfoHeaderFilter.java:9)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:179)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:154)
    at org.springframework.web.filter.CompositeFilter$VirtualFilterChain.doFilter(CompositeFilter.java:108)
    at jetbrains.buildServer.diagnostic.web.DiagnosticFilter.doFilter(DiagnosticFilter.java:8)
    at org.springframework.web.filter.CompositeFilter$VirtualFilterChain.doFilter(CompositeFilter.java:113)
    at jetbrains.buildServer.web.DependencyParametersCalculationContextFilter.doFilter(DependencyParametersCalculationContextFilter.java:2)
    at org.springframework.web.filter.CompositeFilter$VirtualFilterChain.doFilter(CompositeFilter.java:113)
    at jetbrains.buildServer.diagnostic.web.HttpRequestsDurationMetricsReporter.doFilter(HttpRequestsDurationMetricsReporter.java:5)
    at org.springframework.web.filter.CompositeFilter$VirtualFilterChain.doFilter(CompositeFilter.java:113)
    at jetbrains.buildServer.web.HttpSecurityHeadersFilter.doFilter(HttpSecurityHeadersFilter.java:29)
    at org.springframework.web.filter.CompositeFilter$VirtualFilterChain.doFilter(CompositeFilter.java:113)
    at jetbrains.buildServer.controllers.filters.InvalidPathPattermsFilter.doFilter(InvalidPathPattermsFilter.java:14)
    at org.springframework.web.filter.CompositeFilter$VirtualFilterChain.doFilter(CompositeFilter.java:113)
    at jetbrains.buildServer.controllers.filters.DisableSessionCookieTokenAuthFilter.doFilter(DisableSessionCookieTokenAuthFilter.java:4)
    at org.springframework.web.filter.CompositeFilter$VirtualFilterChain.doFilter(CompositeFilter.java:113)
    at jetbrains.buildServer.controllers.filters.ProxyDetailsFilter.doFilter(ProxyDetailsFilter.java:9)
    at org.springframework.web.filter.CompositeFilter$VirtualFilterChain.doFilter(CompositeFilter.java:113)
    at jetbrains.buildServer.controllers.filters.ClearSecurityContextFilter.doFilter(ClearSecurityContextFilter.java:24)
    at org.springframework.web.filter.CompositeFilter$VirtualFilterChain.doFilter(CompositeFilter.java:113)
    at org.springframework.web.filter.CompositeFilter.doFilter(CompositeFilter.java:74)
    at jetbrains.buildServer.web.DelegatingFilter.doFilter(DelegatingFilter.java:74)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:179)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:154)
    at jetbrains.buildServer.web.ResponseFragmentFilter.doFilter(ResponseFragmentFilter.java:27)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:179)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:154)
    at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:168)
    at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:90)
    at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:481)
    at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:130)
    at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:93)
    at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:74)
    at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:346)
    at org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:390)
    at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:63)
    at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:928)
    at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1786)
    at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:52)
    at org.apache.tomcat.util.threads.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1191)
    at org.apache.tomcat.util.threads.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:659)
    at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:63)
    at java.base/java.lang.Thread.run(Thread.java:840)

Your Environment

  • tcWebHooks Version:
  • TeamCity Version: 2024.03
  • TeamCity server Operating System: Mac
  • Are you using a WebHook Template?: No
@netwolfuk
Copy link
Member

I suspect the same will happen when editing a webhook via the REST api (which is how it works on a project edit page)

@netwolfuk
Copy link
Member

I have a fix that looks like it works. I need to get the coverage up on this code, but will try to push later today or tomorrow.

@netwolfuk
Copy link
Member

BTW, I found another bug. Copying a project that contains webhooks with specific builds configured does not update those WebHooks with the new buildType ids in the new project.

@netwolfuk
Copy link
Member

netwolfuk commented Apr 25, 2024

So it looks like copying a project fires off the projectCreated event. There is no "projectCopied" event that I can find.

If a project is new, then it won't have webhooks configured. However, if it has some configured AND any webhook specifically references a buildId AND that buildId does not correspond to a build in the newly created project, I can assume it was a copy, not a create.

Since I have the old buildId, I can then find that old build, get the name, find one in the new project with the same name, and swap the buildId in my webhook configs.

edit: Name might not be unique in a project, so using BuildTypeExternalId and parsing it to match the new project (eg, .endsWith() might be safer.

@matt-richardson
Copy link
Contributor Author

BTW, I found another bug. Copying a project that contains webhooks with specific builds configured does not update those WebHooks with the new buildType ids in the new project.

it's the gift that keeps on giving :wry-smile:

@netwolfuk
Copy link
Member

New commit pushed. It will build soon. No coverage improvements yet, but now has support for deleted builds.

@matt-richardson
Copy link
Contributor Author

Finally got a chance to do some testing on this...

On first try I got a 404 trying to edit the webhook, which I couldn't repro, which was annoying.
I couldn't find anything in the logs though, double annoying.

I cleared out the logs (to get rid of the noise), then restarted the server, then tried again, noting down what I did as I went:

  1. create project in the root called "Testing tcWebhooks Issue 242
  2. create subproject "Sub Project 1"
  3. create build config "Build Config 1" in "Sub Project 1"
  4. create build config "Build Config 2" in "Sub Project 1"
  5. create a webhook in "Sub Project 1", but disable it for "Build Config 2"
  6. delete "Build Config 2"
  7. edit the webhook - shows correctly, saves correctly
  8. create build config "Build Config 3" in "Sub Project 1"
  9. edit the webhook - shows correctly
  10. copy "Sub Project 1" to "Sub Project 2"
  11. go edit the webhook - shows correctly
  12. enable the webhook in "Sub Project 2" for "Build Config 2", saves correctly
  13. copy "Sub Project 2" to "Sub Project 3"
  14. click on webhooks, webhook does not appear on Sub Project 3
  15. refresh after ~15 seconds, webhook appears
  16. edit the webhook, no builds selected

I think 14 is related to the 10 second delay (if that's still in there), but not sure what's the go with 16.

I reckon we're at "usable", but there's still some gremlins in there.

@netwolfuk
Copy link
Member

I found another event that might help.
projects.ProjectEventsNotifier - Attempting to publish event about projectExtId TcPlugins3. Cause projectPersisted
This might be useful to speed up the 10 second window (14). At this point, I don't know why (moved, created, etc).

With regards to 16, I have not written that part yet. The last couple of weeks have been crazy busy.

@matt-richardson
Copy link
Contributor Author

With regards to 16, I have not written that part yet. The last couple of weeks have been crazy busy.

I know that feeling all too well :)
No rush, no stress - appreciate all the work you're putting in here.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

2 participants