halo-dev/plugin-comment-widget

bug:启用pjax后,使用浏览器返回键返回到有评论组件的文章会提示加载失败

mjsoftking opened this issue · 10 comments

bug:启用pjax后,使用浏览器返回键返回到有评论组件的文章会提示加载失败
image

GET https://www.sw0.top/apis/api.halo.run/v1alpha1/comments?group=&kind=&name=&page=1&size=20&version= 400 (Bad Request)

好像是参数没了

看代码是这样加载的

        <halo:comment
                group="content.halo.run"
                th:kind="${type}"
                th:attr="name=${post.metadata.name}"

这种现象发生后可以评论,评论后后台会报错
image

只能在数据库中找到相关记录删除才行

2024-03-10T18:32:28.786+08:00 ERROR 7 --- [tor-tcp-epoll-6] a.w.r.e.AbstractErrorWebExceptionHandler : [13765d67-10156]  500 Server Error for HTTP GET "/apis/api.console.halo.run/v1alpha1/comments?keyword=&page=1&size=20"

java.lang.IllegalArgumentException: Version must not be blank
	at org.springframework.util.Assert.hasText(Assert.java:240) ~[spring-core-6.1.4.jar:6.1.4]
	Suppressed: reactor.core.publisher.FluxOnAssembly$OnAssemblyException: 
Error has been observed at the following site(s):
	*__checkpoint ⇢ run.halo.app.security.InitializeRedirectionWebFilter [DefaultWebFilterChain]
	*__checkpoint ⇢ AuthorizationWebFilter [DefaultWebFilterChain]
	*__checkpoint ⇢ ExceptionTranslationWebFilter [DefaultWebFilterChain]
	*__checkpoint ⇢ LogoutWebFilter [DefaultWebFilterChain]
	*__checkpoint ⇢ ServerRequestCacheWebFilter [DefaultWebFilterChain]
	*__checkpoint ⇢ SecurityContextServerWebExchangeWebFilter [DefaultWebFilterChain]
	*__checkpoint ⇢ LogoutPageGeneratingWebFilter [DefaultWebFilterChain]
	*__checkpoint ⇢ AnonymousAuthenticationWebFilter [DefaultWebFilterChain]
	*__checkpoint ⇢ SecurityWebFilterChainProxy [DefaultWebFilterChain]
	*__checkpoint ⇢ TotpAuthenticationFilter [DefaultWebFilterChain]
	*__checkpoint ⇢ AuthenticationWebFilter [DefaultWebFilterChain]
	*__checkpoint ⇢ SecurityWebFilterChainProxy [DefaultWebFilterChain]
	*__checkpoint ⇢ SecurityWebFilterChainProxy [DefaultWebFilterChain]
	*__checkpoint ⇢ AuthenticationWebFilter [DefaultWebFilterChain]
	*__checkpoint ⇢ AuthenticationWebFilter [DefaultWebFilterChain]
	*__checkpoint ⇢ ReactorContextWebFilter [DefaultWebFilterChain]
	*__checkpoint ⇢ CsrfWebFilter [DefaultWebFilterChain]
	*__checkpoint ⇢ CorsWebFilter [DefaultWebFilterChain]
	*__checkpoint ⇢ HttpHeaderWriterWebFilter [DefaultWebFilterChain]
	*__checkpoint ⇢ ServerWebExchangeReactorContextWebFilter [DefaultWebFilterChain]
	*__checkpoint ⇢ org.springframework.security.web.server.WebFilterChainProxy [DefaultWebFilterChain]
	*__checkpoint ⇢ run.halo.social.login.security.SocialAuthenticatorFilter [DefaultWebFilterChain]
	*__checkpoint ⇢ run.halo.oauth.Oauth2Authenticator [DefaultWebFilterChain]
	*__checkpoint ⇢ run.halo.social.login.security.SocialAuthorizationRequestRedirectWebFilter [DefaultWebFilterChain]
	*__checkpoint ⇢ run.halo.oauth.Oauth2AuthorizationRequestRedirectWebFilter [DefaultWebFilterChain]
	*__checkpoint ⇢ run.halo.app.webfilter.AdditionalWebFilterChainProxy [DefaultWebFilterChain]
	*__checkpoint ⇢ HTTP GET "/apis/api.console.halo.run/v1alpha1/comments?keyword=&page=1&size=20" [ExceptionHandlingWebHandler]
Original Stack Trace:
		at org.springframework.util.Assert.hasText(Assert.java:240) ~[spring-core-6.1.4.jar:6.1.4]
		at run.halo.app.extension.GroupVersionKind.<init>(GroupVersionKind.java:17) ~[api-2.13.1.jar:2.13.1]
		at run.halo.moments.MomentCommentSubject.supports(MomentCommentSubject.java:52) ~[na:na]
		at run.halo.app.content.comment.CommentServiceImpl.lambda$getCommentSubject$11(CommentServiceImpl.java:190) ~[classes/:2.13.1]
		at java.base/java.util.stream.ReferencePipeline$2$1.accept(Unknown Source) ~[na:na]
		at java.base/java.util.AbstractList$RandomAccessSpliterator.tryAdvance(Unknown Source) ~[na:na]
		at java.base/java.util.stream.ReferencePipeline.forEachWithCancel(Unknown Source) ~[na:na]
		at java.base/java.util.stream.AbstractPipeline.copyIntoWithCancel(Unknown Source) ~[na:na]
		at java.base/java.util.stream.AbstractPipeline.copyInto(Unknown Source) ~[na:na]
		at java.base/java.util.stream.AbstractPipeline.wrapAndCopyInto(Unknown Source) ~[na:na]
		at java.base/java.util.stream.FindOps$FindOp.evaluateSequential(Unknown Source) ~[na:na]
		at java.base/java.util.stream.AbstractPipeline.evaluate(Unknown Source) ~[na:na]
		at java.base/java.util.stream.ReferencePipeline.findFirst(Unknown Source) ~[na:na]
		at run.halo.app.content.comment.CommentServiceImpl.getCommentSubject(CommentServiceImpl.java:191) ~[classes/:2.13.1]
		at run.halo.app.content.comment.CommentServiceImpl.lambda$toListedComment$8(CommentServiceImpl.java:150) ~[classes/:2.13.1]
		at reactor.core.publisher.MonoFlatMap$FlatMapMain.onNext(MonoFlatMap.java:132) ~[reactor-core-3.6.3.jar:3.6.3]
		at reactor.core.publisher.FluxHide$SuppressFuseableSubscriber.onNext(FluxHide.java:137) ~[reactor-core-3.6.3.jar:3.6.3]
		at reactor.core.publisher.FluxMap$MapSubscriber.onNext(FluxMap.java:122) ~[reactor-core-3.6.3.jar:3.6.3]
		at reactor.core.publisher.FluxMap$MapSubscriber.onNext(FluxMap.java:122) ~[reactor-core-3.6.3.jar:3.6.3]
		at reactor.core.publisher.FluxSwitchIfEmpty$SwitchIfEmptySubscriber.onNext(FluxSwitchIfEmpty.java:74) ~[reactor-core-3.6.3.jar:3.6.3]
		at reactor.core.publisher.FluxMap$MapSubscriber.onNext(FluxMap.java:122) ~[reactor-core-3.6.3.jar:3.6.3]
		at reactor.core.publisher.MonoUsingWhen$MonoUsingWhenSubscriber.deferredComplete(MonoUsingWhen.java:268) ~[reactor-core-3.6.3.jar:3.6.3]
		at reactor.core.publisher.FluxUsingWhen$CommitInner.onComplete(FluxUsingWhen.java:532) ~[reactor-core-3.6.3.jar:3.6.3]
		at reactor.core.publisher.Operators.complete(Operators.java:137) ~[reactor-core-3.6.3.jar:3.6.3]
		at reactor.core.publisher.MonoEmpty.subscribe(MonoEmpty.java:46) ~[reactor-core-3.6.3.jar:3.6.3]
		at reactor.core.publisher.Mono.subscribe(Mono.java:4563) ~[reactor-core-3.6.3.jar:3.6.3]
		at reactor.core.publisher.FluxUsingWhen$UsingWhenSubscriber.onComplete(FluxUsingWhen.java:389) ~[reactor-core-3.6.3.jar:3.6.3]
		at reactor.core.publisher.MonoFlatMap$FlatMapMain.onNext(MonoFlatMap.java:159) ~[reactor-core-3.6.3.jar:3.6.3]
		at reactor.core.publisher.FluxOnErrorResume$ResumeSubscriber.onNext(FluxOnErrorResume.java:79) ~[reactor-core-3.6.3.jar:3.6.3]
		at reactor.core.publisher.Operators$MonoInnerProducerBase.complete(Operators.java:2842) ~[reactor-core-3.6.3.jar:3.6.3]
		at reactor.core.publisher.MonoSingle$SingleSubscriber.onComplete(MonoSingle.java:180) ~[reactor-core-3.6.3.jar:3.6.3]
		at reactor.core.publisher.Operators$MultiSubscriptionSubscriber.onComplete(Operators.java:2231) ~[reactor-core-3.6.3.jar:3.6.3]
		at reactor.core.publisher.FluxUsingWhen$UsingWhenSubscriber.deferredComplete(FluxUsingWhen.java:397) ~[reactor-core-3.6.3.jar:3.6.3]
		at reactor.core.publisher.FluxUsingWhen$CommitInner.onComplete(FluxUsingWhen.java:532) ~[reactor-core-3.6.3.jar:3.6.3]
		at reactor.core.publisher.Operators$MultiSubscriptionSubscriber.onComplete(Operators.java:2231) ~[reactor-core-3.6.3.jar:3.6.3]
		at reactor.core.publisher.FluxPeek$PeekSubscriber.onComplete(FluxPeek.java:260) ~[reactor-core-3.6.3.jar:3.6.3]
		at reactor.core.publisher.Operators$MultiSubscriptionSubscriber.onComplete(Operators.java:2231) ~[reactor-core-3.6.3.jar:3.6.3]
		at reactor.core.publisher.MonoIgnoreThen$ThenIgnoreMain.onComplete(MonoIgnoreThen.java:210) ~[reactor-core-3.6.3.jar:3.6.3]
		at reactor.core.publisher.MonoIgnoreThen$ThenIgnoreMain.onComplete(MonoIgnoreThen.java:210) ~[reactor-core-3.6.3.jar:3.6.3]
		at reactor.pool.SimpleDequePool.maybeRecycleAndDrain(SimpleDequePool.java:540) ~[reactor-pool-1.0.5.jar:1.0.5]
		at reactor.pool.SimpleDequePool$QueuePoolRecyclerInner.onComplete(SimpleDequePool.java:770) ~[reactor-pool-1.0.5.jar:1.0.5]
		at reactor.core.publisher.Operators.complete(Operators.java:137) ~[reactor-core-3.6.3.jar:3.6.3]
		at reactor.core.publisher.MonoEmpty.subscribe(MonoEmpty.java:46) ~[reactor-core-3.6.3.jar:3.6.3]
		at reactor.core.publisher.Mono.subscribe(Mono.java:4563) ~[reactor-core-3.6.3.jar:3.6.3]
		at reactor.pool.SimpleDequePool$QueuePoolRecyclerMono.subscribe(SimpleDequePool.java:882) ~[reactor-pool-1.0.5.jar:1.0.5]
		at reactor.core.publisher.MonoDefer.subscribe(MonoDefer.java:53) ~[reactor-core-3.6.3.jar:3.6.3]
		at reactor.core.publisher.MonoIgnoreThen$ThenIgnoreMain.subscribeNext(MonoIgnoreThen.java:241) ~[reactor-core-3.6.3.jar:3.6.3]
		at reactor.core.publisher.MonoIgnoreThen$ThenIgnoreMain.onComplete(MonoIgnoreThen.java:204) ~[reactor-core-3.6.3.jar:3.6.3]
		at reactor.core.publisher.FluxPeek$PeekSubscriber.onComplete(FluxPeek.java:260) ~[reactor-core-3.6.3.jar:3.6.3]
		at reactor.core.publisher.MonoIgnoreElements$IgnoreElementsSubscriber.onComplete(MonoIgnoreElements.java:89) ~[reactor-core-3.6.3.jar:3.6.3]
		at reactor.core.publisher.MonoFlatMapMany$FlatMapManyInner.onComplete(MonoFlatMapMany.java:261) ~[reactor-core-3.6.3.jar:3.6.3]
		at reactor.core.publisher.FluxPeekFuseable$PeekFuseableSubscriber.onComplete(FluxPeekFuseable.java:277) ~[reactor-core-3.6.3.jar:3.6.3]
		at reactor.core.publisher.FluxContextWrite$ContextWriteSubscriber.onComplete(FluxContextWrite.java:126) ~[reactor-core-3.6.3.jar:3.6.3]
		at io.asyncer.r2dbc.mysql.internal.util.DiscardOnCancelSubscriber.onComplete(DiscardOnCancelSubscriber.java:84) ~[r2dbc-mysql-1.0.6.jar:1.0.6]
		at reactor.core.publisher.FluxPeekFuseable$PeekConditionalSubscriber.onComplete(FluxPeekFuseable.java:940) ~[reactor-core-3.6.3.jar:3.6.3]
		at reactor.core.publisher.FluxHandle$HandleConditionalSubscriber.onNext(FluxHandle.java:359) ~[reactor-core-3.6.3.jar:3.6.3]
		at reactor.core.publisher.FluxPeekFuseable$PeekConditionalSubscriber.onNext(FluxPeekFuseable.java:854) ~[reactor-core-3.6.3.jar:3.6.3]
		at reactor.core.publisher.SinkManyEmitterProcessor.drain(SinkManyEmitterProcessor.java:476) ~[reactor-core-3.6.3.jar:3.6.3]
		at reactor.core.publisher.SinkManyEmitterProcessor.tryEmitNext(SinkManyEmitterProcessor.java:273) ~[reactor-core-3.6.3.jar:3.6.3]
		at reactor.core.publisher.SinkManySerialized.tryEmitNext(SinkManySerialized.java:100) ~[reactor-core-3.6.3.jar:3.6.3]
		at reactor.core.publisher.InternalManySink.emitNext(InternalManySink.java:27) ~[reactor-core-3.6.3.jar:3.6.3]
		at io.asyncer.r2dbc.mysql.client.ReactorNettyClient$ResponseSink.next(ReactorNettyClient.java:383) ~[r2dbc-mysql-1.0.6.jar:1.0.6]
		at io.asyncer.r2dbc.mysql.client.ReactorNettyClient.lambda$new$0(ReactorNettyClient.java:121) ~[r2dbc-mysql-1.0.6.jar:1.0.6]
		at reactor.core.publisher.FluxPeek$PeekSubscriber.onNext(FluxPeek.java:185) ~[reactor-core-3.6.3.jar:3.6.3]
		at reactor.netty.channel.FluxReceive.drainReceiver(FluxReceive.java:294) ~[reactor-netty-core-1.1.16.jar:1.1.16]
		at reactor.netty.channel.FluxReceive.onInboundNext(FluxReceive.java:403) ~[reactor-netty-core-1.1.16.jar:1.1.16]
		at reactor.netty.channel.ChannelOperations.onInboundNext(ChannelOperations.java:426) ~[reactor-netty-core-1.1.16.jar:1.1.16]
		at reactor.netty.channel.ChannelOperationsHandler.channelRead(ChannelOperationsHandler.java:114) ~[reactor-netty-core-1.1.16.jar:1.1.16]
		at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:444) ~[netty-transport-4.1.107.Final.jar:4.1.107.Final]
		at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:420) ~[netty-transport-4.1.107.Final.jar:4.1.107.Final]
		at io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:412) ~[netty-transport-4.1.107.Final.jar:4.1.107.Final]
		at io.asyncer.r2dbc.mysql.client.MessageDuplexCodec.handleDecoded(MessageDuplexCodec.java:162) ~[r2dbc-mysql-1.0.6.jar:1.0.6]
		at io.asyncer.r2dbc.mysql.client.MessageDuplexCodec.channelRead(MessageDuplexCodec.java:73) ~[r2dbc-mysql-1.0.6.jar:1.0.6]
		at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:442) ~[netty-transport-4.1.107.Final.jar:4.1.107.Final]
		at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:420) ~[netty-transport-4.1.107.Final.jar:4.1.107.Final]
		at io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:412) ~[netty-transport-4.1.107.Final.jar:4.1.107.Final]
		at io.netty.handler.codec.ByteToMessageDecoder.fireChannelRead(ByteToMessageDecoder.java:346) ~[netty-codec-4.1.107.Final.jar:4.1.107.Final]
		at io.netty.handler.codec.ByteToMessageDecoder.channelRead(ByteToMessageDecoder.java:318) ~[netty-codec-4.1.107.Final.jar:4.1.107.Final]
		at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:444) ~[netty-transport-4.1.107.Final.jar:4.1.107.Final]
		at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:420) ~[netty-transport-4.1.107.Final.jar:4.1.107.Final]
		at io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:412) ~[netty-transport-4.1.107.Final.jar:4.1.107.Final]
		at io.netty.handler.ssl.SslHandler.unwrap(SslHandler.java:1475) ~[netty-handler-4.1.107.Final.jar:4.1.107.Final]
		at io.netty.handler.ssl.SslHandler.decodeJdkCompatible(SslHandler.java:1338) ~[netty-handler-4.1.107.Final.jar:4.1.107.Final]
		at io.netty.handler.ssl.SslHandler.decode(SslHandler.java:1387) ~[netty-handler-4.1.107.Final.jar:4.1.107.Final]
		at io.netty.handler.codec.ByteToMessageDecoder.decodeRemovalReentryProtection(ByteToMessageDecoder.java:529) ~[netty-codec-4.1.107.Final.jar:4.1.107.Final]
		at io.netty.handler.codec.ByteToMessageDecoder.callDecode(ByteToMessageDecoder.java:468) ~[netty-codec-4.1.107.Final.jar:4.1.107.Final]
		at io.netty.handler.codec.ByteToMessageDecoder.channelRead(ByteToMessageDecoder.java:290) ~[netty-codec-4.1.107.Final.jar:4.1.107.Final]
		at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:444) ~[netty-transport-4.1.107.Final.jar:4.1.107.Final]
		at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:420) ~[netty-transport-4.1.107.Final.jar:4.1.107.Final]
		at io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:412) ~[netty-transport-4.1.107.Final.jar:4.1.107.Final]
		at io.netty.channel.DefaultChannelPipeline$HeadContext.channelRead(DefaultChannelPipeline.java:1410) ~[netty-transport-4.1.107.Final.jar:4.1.107.Final]
		at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:440) ~[netty-transport-4.1.107.Final.jar:4.1.107.Final]
		at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:420) ~[netty-transport-4.1.107.Final.jar:4.1.107.Final]
		at io.netty.channel.DefaultChannelPipeline.fireChannelRead(DefaultChannelPipeline.java:919) ~[netty-transport-4.1.107.Final.jar:4.1.107.Final]
		at io.netty.channel.epoll.AbstractEpollStreamChannel$EpollStreamUnsafe.epollInReady(AbstractEpollStreamChannel.java:800) ~[netty-transport-classes-epoll-4.1.107.Final.jar:4.1.107.Final]
		at io.netty.channel.epoll.EpollEventLoop.processReady(EpollEventLoop.java:509) ~[netty-transport-classes-epoll-4.1.107.Final.jar:4.1.107.Final]
		at io.netty.channel.epoll.EpollEventLoop.run(EpollEventLoop.java:407) ~[netty-transport-classes-epoll-4.1.107.Final.jar:4.1.107.Final]
		at io.netty.util.concurrent.SingleThreadEventExecutor$4.run(SingleThreadEventExecutor.java:997) ~[netty-common-4.1.107.Final.jar:4.1.107.Final]
		at io.netty.util.internal.ThreadExecutorMap$2.run(ThreadExecutorMap.java:74) ~[netty-common-4.1.107.Final.jar:4.1.107.Final]
		at io.netty.util.concurrent.FastThreadLocalRunnable.run(FastThreadLocalRunnable.java:30) ~[netty-common-4.1.107.Final.jar:4.1.107.Final]
		at java.base/java.lang.Thread.run(Unknown Source) ~[na:na]

请提供主题使用方式,我并未在其他使用 pjax 的主题上复现。

是下面这段代码造成的:

halo-sigs/plugin-moments@574ce11/src/main/java/run/halo/moments/MomentCommentSubject.java#L53

前端未传 gvk 应该和这个无关。

@ruibaby

https://web.ugreen.cloud/web/#/share/EC-uUvx554JJ492YbEa-203307 提取码:D7P3

  • 报错是使用鼠标侧键进行返回的,和点击浏览器后推键一样,只要返回到有评论组件的就会报错。
  • 实际测试:打开一篇带有评论组件的文章使评论加载出来,然后直接在打开一篇带有评论的文章也要把评论组件打开,然后是用侧键或者浏览器返回键返回就会发生。

主题加载组件方式:

 <halo:comment
                group="content.halo.run"
                th:kind="${type}"
                th:attr="name=${post.metadata.name}"

不确定是否是需要在pajx加载后进行特殊处理还是完全由组件加载的

主题是哪个?我测试一下。

halo-theme-dream2.0-V1.3.0.41.zip
dream2.0的,在调整,看文档只需要加载那个自定义组件就行,没写其他的
所以现在不确定是需要主题做些特殊操作还是怎么回事

        <comment-widget
                group="content.halo.run"
                th:kind="${type}"
                version="v1alpha1"
                th:name="${post.metadata.name}"
        ></comment-widget>

改成这种形式就没问题了

        <comment-widget
                group="content.halo.run"
                th:kind="${type}"
                version="v1alpha1"
                th:name="${post.metadata.name}"
        ></comment-widget>

改成这种形式就没问题了

这种形式是直接作为 Web Component 使用,可能在这种场景下确实没问题。之前的问题可能出在 init 方法,我会在排查一下。

@ruibaby 幸苦了,这种方式测试后发现实际会导致打开文章自动滚动到评论的位置,会略过全部内容直接显示评论,但是无论怎么前进后退都读取正常

@ruibaby 幸苦了,这种方式测试后发现实际会导致打开文章自动滚动到评论的位置,会略过全部内容直接显示评论,但是无论怎么前进后退都读取正常

已知问题,将在 #98 中修复。