You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Haskell通知服务器调用notify-send报“Unexpected reply type”错误排查

Haskell通知服务器notify-send报错"Unexpected reply type"的解决办法

问题原因

你代码里的notifyInSignature对hints的类型声明错误。通知协议里的hints是a{sv}类型——即键为字符串、值为任意类型Variant的字典,但你写成了TypeDictionary TypeString TypeString,强制要求值为字符串类型。

虽然你的程序能正常打印参数,但DBus的类型校验机制会因为输入签名不匹配,导致notify-send收到的回复不符合预期,最终抛出"Unexpected reply type"错误。

修复方案

只需要修正notifyInSignature里的hints类型:
把TypeDictionary TypeString TypeString替换成TypeDictionary TypeString TypeVariant,让字典的值支持任意Variant类型,和协议要求一致。

返回值ReplyReturn [toVariant (0::Int32)]是符合要求的,Notify方法确实需要返回单个Int32类型的通知ID。

修复后的完整代码

{-# LANGUAGE OverloadedStrings #-}

import DBus
import DBus.Client
import Data.Int
import Control.Monad
import Control.Monad.IO.Class
import Control.Concurrent

notifyInSignature = [
    TypeString,
    TypeInt32,
    TypeString,
    TypeString,
    TypeString,
    TypeArray TypeString,
    TypeDictionary TypeString TypeVariant,  -- 修正此处的类型
    TypeInt32
  ]

notify :: MethodCall -> DBusR Reply
notify mCall = do
    liftIO $ mapM_ print [name, rid, icon, summary, body, actions, hints, expire]
    return reply
      where reply = ReplyReturn [toVariant (0::Int32)]
            [name, rid, icon, summary, body, actions, hints, expire] = methodCallBody mCall

getServerInformation :: IO (String, String, String, String)
getServerInformation = return ("name", "vendor", "version", "spec version")

getCapabilities :: IO [String]
getCapabilities = return ["body"]

main :: IO ()
main = do
    client <- connectSession

    export client "/org/freedesktop/Notifications" defaultInterface {
          interfaceName = "org.freedesktop.Notifications",
          interfaceMethods = [
          autoMethod "GetServerInformation" getServerInformation,
          autoMethod "GetCapabilities" getCapabilities,
          makeMethod "Notify" (signature_ notifyInSignature) (signature_ [TypeInt32]) notify
        ]
    }
    reply <- requestName client "org.freedesktop.Notifications" []
    print reply
    forever (threadDelay 1000000)

测试验证

按原步骤重新操作:

  1. 停止dunst等官方通知服务器:kill $(pidof dunst)
  2. 运行修复后的Haskell代码,控制台打印NamePrimaryOwner后等待
  3. 执行notify-send 'sum' 'body 1' -t 1234

此时notify-send不会再报错,Haskell终端依然能正确打印所有通知参数。

内容的提问来源于stack exchange,提问作者Enlico

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.28 22:43:27