-
Bug
-
Resolution: Fixed
-
Medium
-
5.14.0, 5.13.1
-
Severity 2 - Major
-
Summary
In-browser editing hangs on the commit dialog with JS error if the commit was rejected by a pre-commit hook with RepositoryHookVetoedException
The issue can be reproduced with External Hooks with no error in the user interface.
By the same time in console client, the whole procedure is going well and generating correct RepositoryHookVetoedException.
Steps to Reproduce
- Install the latest External Hooks addon
- Install the executable script in application-data/bitbucket/external-hooks (for example preventing editing certain types of files)
- Create a repository in Bitbucket
- Go to test4 Repository Settings -> Hooks and enable the External Pre Receive Hook
- In the External Pre Receive Hook config, set:
- Executable: filename.sh
- Safe Mode: Enable
- Positional parameters: Leave empty
- Push an empty file to the test4 repo. Name the file 'test.lua'. (if the hook prevents online editing of lua files)
- Open the pushed file in Bitbucket In-browser editor and add some text
- Push Commit
- Edit or keep the message and click Commit again
Another option would be to develop own pre-commit hook add-on which generates RepositoryHookVetoedException
Expected Results
The commit showing an error message pop-up with the text from RepositoryHookVetoedException
Actual Results
The dialog hags indefinitely and JS console in the browser is showing an error:
Uncaught TypeError: a.replace is not a function at c (internal-src-js-aui-…7a2c&locale=en-US:1) at Object.<anonymous> (commit-dialog.js?_st…acf0&locale=en-US:8) at Object.<anonymous> (jquery.js?_statichas…a2c&locale=en-US:97) at k (jquery.js?_statichas…a2c&locale=en-US:94) at Object.fireWith [as rejectWith] (jquery.js?_statichas…a2c&locale=en-US:96) at Object.f.(:25131/b5131/project…/anonymous function) (http://localhost:25131/b5131/s/7b16bff…-CDN/1854562…5940567a2c/_/download/contextbatch/js/_super/batch.js?locale=en-US:125:153) at k (jquery.js?_statichas…a2c&locale=en-US:94) at Object.fireWith [as rejectWith] (jquery.js?_statichas…a2c&locale=en-US:96) at Object.f.(:25131/b5131/project…/anonymous function) (http://localhost:25131/b5131/s/7b16bff…-CDN/1854562…5940567a2c/_/download/contextbatch/js/_super/batch.js?locale=en-US:125:153) at k (jquery.js?_statichas…a2c&locale=en-US:94)
The below exception is thrown in the atlassian-bitbucket.log file:
2018-09-21 16:04:19,911 INFO [http-nio-25131-exec-4] admin @124C9S8x964x270x0 1uuzxas 0:0:0:0:0:0:0:1 "PUT /rest/api/latest/projects/DEMO/repos/temp/browse/test.lua HTTP/1.1" c.a.s.i.h.r.DefaultRepositoryHookService [DEMO/temp[1]] hook 'external-pre-receive-hook' vetoed the file-edit request 2018-09-21 16:04:19,919 DEBUG [http-nio-25131-exec-4] admin @124C9S8x964x270x0 1uuzxas 0:0:0:0:0:0:0:1 "PUT /rest/api/latest/projects/DEMO/repos/temp/browse/test.lua HTTP/1.1" c.a.s.i.r.e.ServiceExceptionMapper Mapping ServiceException to REST response 400 com.atlassian.bitbucket.hook.repository.RepositoryHookVetoedException: File editing canceled for 'test.lua' on 'newbranch'. at com.atlassian.stash.internal.scm.git.DefaultGitExtendedCommandFactory$EditFileHookInvoker.callPreUpdate(DefaultGitExtendedCommandFactory.java:325) at com.atlassian.stash.internal.scm.git.fetch.ObjectFetchStrategy.fetch(ObjectFetchStrategy.java:119) at com.atlassian.stash.internal.scm.git.command.file.EditFileCommand.call(EditFileCommand.java:172) at com.atlassian.stash.internal.scm.git.command.file.EditFileCommand.call(EditFileCommand.java:73) at com.atlassian.stash.internal.content.DefaultContentService.editFile(DefaultContentService.java:107) at com.atlassian.plugin.util.ContextClassLoaderSettingInvocationHandler.invoke(ContextClassLoaderSettingInvocationHandler.java:26) at org.eclipse.gemini.blueprint.service.importer.support.internal.aop.ServiceInvoker.doInvoke(ServiceInvoker.java:56) at org.eclipse.gemini.blueprint.service.importer.support.internal.aop.ServiceInvoker.invoke(ServiceInvoker.java:60) at org.eclipse.gemini.blueprint.service.util.internal.aop.ServiceTCCLInterceptor.invokeUnprivileged(ServiceTCCLInterceptor.java:70) at org.eclipse.gemini.blueprint.service.util.internal.aop.ServiceTCCLInterceptor.invoke(ServiceTCCLInterceptor.java:53) at org.eclipse.gemini.blueprint.service.importer.support.LocalBundleContextAdvice.invoke(LocalBundleContextAdvice.java:57) at com.atlassian.stash.internal.rest.content.ContentResource.editFile(ContentResource.java:294) at com.atlassian.applinks.core.rest.context.ContextFilter.doFilter(ContextFilter.java:24) at com.atlassian.applinks.core.rest.context.ContextFilter.doFilter(ContextFilter.java:24) at com.atlassian.applinks.core.rest.context.ContextFilter.doFilter(ContextFilter.java:24) at com.atlassian.applinks.core.rest.context.ContextFilter.doFilter(ContextFilter.java:24) at com.atlassian.applinks.core.rest.context.ContextFilter.doFilter(ContextFilter.java:24) at com.atlassian.analytics.client.filter.UniversalAnalyticsFilter.doFilter(UniversalAnalyticsFilter.java:92) at com.atlassian.analytics.client.filter.AbstractHttpFilter.doFilter(AbstractHttpFilter.java:39) at com.atlassian.bitbucket.internal.xcode.web.XcodeUserAgentFilter.doFilter(XcodeUserAgentFilter.java:36) at com.atlassian.stash.internal.spring.lifecycle.LifecycleJohnsonServletFilterModuleContainerFilter.doFilter(LifecycleJohnsonServletFilterModuleContainerFilter.java:42) at com.atlassian.plugin.connect.plugin.auth.scope.ApiScopingFilter.doFilter(ApiScopingFilter.java:81) at com.atlassian.stash.internal.spring.lifecycle.LifecycleJohnsonServletFilterModuleContainerFilter.doFilter(LifecycleJohnsonServletFilterModuleContainerFilter.java:42) at com.atlassian.stash.internal.spring.security.StashAuthenticationFilter.doFilter(StashAuthenticationFilter.java:85) at com.atlassian.stash.internal.web.auth.BeforeLoginPluginAuthenticationFilter.doInsideSpringSecurityChain(BeforeLoginPluginAuthenticationFilter.java:112) at com.atlassian.stash.internal.web.auth.BeforeLoginPluginAuthenticationFilter.doFilter(BeforeLoginPluginAuthenticationFilter.java:75) at com.atlassian.security.auth.trustedapps.filter.TrustedApplicationsFilter.doFilter(TrustedApplicationsFilter.java:94) at com.atlassian.oauth.serviceprovider.internal.servlet.OAuthFilter.doFilter(OAuthFilter.java:67) at com.atlassian.stash.internal.spring.lifecycle.LifecycleJohnsonServletFilterModuleContainerFilter.doFilter(LifecycleJohnsonServletFilterModuleContainerFilter.java:42) at com.atlassian.plugin.connect.plugin.auth.oauth2.DefaultSalAuthenticationFilter.doFilter(DefaultSalAuthenticationFilter.java:69) at com.atlassian.plugin.connect.plugin.auth.user.ThreeLeggedAuthFilter.doFilter(ThreeLeggedAuthFilter.java:109) at com.atlassian.jwt.internal.servlet.JwtAuthFilter.doFilter(JwtAuthFilter.java:32) at com.atlassian.analytics.client.filter.DefaultAnalyticsFilter.doFilter(DefaultAnalyticsFilter.java:38) at com.atlassian.analytics.client.filter.AbstractHttpFilter.doFilter(AbstractHttpFilter.java:39) at com.atlassian.bitbucket.internal.scm.git.lfs.servlet.filter.GitLfsLockingFilter.doFilter(GitLfsLockingFilter.java:50) at com.atlassian.stash.internal.spring.lifecycle.LifecycleJohnsonServletFilterModuleContainerFilter.doFilter(LifecycleJohnsonServletFilterModuleContainerFilter.java:42) at com.atlassian.stash.internal.web.auth.BeforeLoginPluginAuthenticationFilter.doBeforeBeforeLoginFilters(BeforeLoginPluginAuthenticationFilter.java:90) at com.atlassian.stash.internal.web.auth.BeforeLoginPluginAuthenticationFilter.doFilter(BeforeLoginPluginAuthenticationFilter.java:73) at com.atlassian.stash.internal.request.DefaultRequestManager.doAsRequest(DefaultRequestManager.java:89) at com.atlassian.stash.internal.hazelcast.ConfigurableWebFilter.doFilter(ConfigurableWebFilter.java:38) at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149) at java.lang.Thread.run(Thread.java:748) ... 305 frames trimmed