升級到 WordPress 6.3 遇到的問題

WordPress 6.3 出了:「WordPress 6.3 “Lionel”」,順手按了升級就爛掉了,發現是 admin 介面爛掉,網站本身還能瀏覽,先翻出 PHP 的錯誤訊息:

2023/08/09 04:52:32 [error] 845702#845702: *1350433 FastCGI sent in stderr: "PHP message: PHP Fatal error:  Uncaught ArgumentCountError: Too few arguments to function W3TC\Util_Environment::is_dbcluster(), 0 passed in /srv/blog.gslin.org/public/wp-content/db.php on line 56 and exactly 1 expected in /srv/blog.gslin.org/public/wp-content/plugins/w3-total-cache/Util_Environment.php:176

順著這個訊息找到這個算新的討論:「Fatal error in Util_Environment」,看起來跟 W3 Total Cache 有關。

(話說這個錯誤訊息還比較新,Kagi 上面找不到,後來是在 DuckDuckGo 上找到)

解法就比較粗暴一點,先到 wp-content/plugins 下讓 W3 Total Cache 失效:

sudo chmod 000 w3-total-cache

跑完升級後會出現錯誤訊息提示 W3 Total Cache 沒有啟用,這時候再開回來:

sudo chmod 755 w3-total-cache

後續把 cache 都清掉就正常了。

搞爆 Python 的各種姿勢

Hacker News 首頁上看到「no-op statements syntactically valid only since Python X.Y」這個專案,搞爆各個版本 Python 的各種方式,從 Python 2.4+ 一路到 3.11+ (不過中間有少了 3.2 與 3.4)。

專案要求的條件是 no-op,所以像是 import 這種行為都會產生 side effect,所以就不能用 sys.version_info 這個變數了:

This is a collection of no-op statements that are syntactically valid only since Python X.Y, for most X.Y ≥ 2.4.

看了一下裡面的例子,反而看到一些有趣的東西,像是原來這種語法在 Python 2.3 是不能跑的:

(0 for x in [])  # Python >= 2.4 is required

然後 0_0 這種方便表示數字的寫法在 Python 3.6+ 才能動:

0_0  # Python >= 3.6 is required

有些東西真的是用習慣就忘記了,遇到一些古董環境可能會中獎然後在那邊疑惑半天 XD

看起來這個專案應該比較偏娛樂性質?實際應用上有很多其他比較常見的方式檢查環境才對 XD 但馬上想到,在打黑箱的時候可以用這個方法判斷 Python 的環境版本?

原來 Sentry 有支援 Bash...

Sentry 可以拿來蒐集自己開發軟體的錯誤事件,剛剛突發奇想用搜尋引擎找了一下,發現 Sentry 是有支援 Bash 的:「Sending Sentry Events from Bash」。

文章裡面也直接提到了 hook 的用法,在裝了 sentry-cli 後可以掛進來:

#!/bin/bash
export SENTRY_DSN=
eval "$(sentry-cli bash-hook)"

自己架 Sentry 的步驟我有丟在「Sentry」這邊,或者也可以用雲端的版本。

丟給同事參考看看...

Firefox 87 推出 SmartBlock 阻擋 3rd-party tracking

Firefox 87 推出了 SmartBlock,試著阻擋各種追蹤器:「Firefox 87 introduces SmartBlock for Private Browsing」,不過這不是一般的預設值,而是只有 Strict 模式與無痕模式會用到。

對於追蹤的問題,最早的作法是直接擋掉 3rd-party tracking javascript 的載入,但有很多網站會因為對應的變數沒有初始化而造成 javascript error。

這次的 SmartBlock 其實就是在各家阻擋套件實做很久的方式,插入一小段客製化的 javascript 讓網站裡的 javascript 可以呼叫,但實際上不會送任何資料出去,像是 uBlock Origin 的「unbreak.txt」。

不過 Firefox 重複搞這麼多東西,要不要考慮直接把 uBlock Origin 內建進來啊...

RFC 定義的 application/problem+json (或是 xml)

剛剛在 Clubhouse 上聽到保哥提到了 RFC 7807 這個東西 (Problem Details for HTTP APIs),剛剛翻瀏覽器累積的 tab,發現原來先前有看到,而且有打算要出新版的消息:

RFC 7807 裡面這樣定義的方式可以讓 client 端直接判斷 Content-Type 知道這個回傳資料是不是錯誤訊息,不然以前都是 JSON 就得再另外包裝。用 Content-Type 的作法可以讓判斷條件變得清晰不少。

除了 application/problem+jsonapplication/problem+xml 以外,在「3.1. Members of a Problem Details Object」裡面則是說明 JSON (或是 XML) 裡面有哪些必要以及可選的資訊要填,然後「3.2. Extension Members」這邊則大概描述一下怎麼擴充。

先有個印象,之後新規劃的東西可以考慮進去...

SoundCloud 推出的錯誤蒐集工具 Periskop

SoundCloud 推出的錯誤蒐集工具 Periskop,應該是取自捷克文的 Periskop (潛望鏡):「Periskop: Exception Monitoring Service」。

Sentry 這類工具最大的差異在於是走 pull-based 架構,也就是跟 Prometheus 的設計相同 (Prometheus 也是 SoundCloud 發明的專案)。

就資源上來說,當 instance 上的錯誤滿天飛,而超過 log buffer 時,如果是以巨觀的角度來看,其實掉一些東西也沒關係:

另外也有提到一些缺點:

  • If a fatal exception occurs and the process dies, the exception won’t be collected. However, this can be mitigated by the reporting capabilities of orchestration services like Kubernetes or other forms of logging.
  • The pull model is not well suited for short-lived processes like scheduled jobs. This could be solved by the use of a push-based event gateway, although we haven’t yet had the need at SoundCloud, as it is usually more convenient to use logs to inspect failed jobs.

雖然 web (js) 與 mobile devices 的部份沒辦法被這個服務涵蓋,但一般來說會把面向使用者的服務另外拆開,所以不算是缺點... (像 Sentry 那樣通包,主要還是為了商業上的規劃)

目前看起來還缺一些東西 (就我想用的需求),可以先觀察一下會怎麼發展,另外一邊 Sentry 也在朝 Python 3 進行,也可以嘗試看看...

Facebook 修正錯字的新演算法

先前 Facebook 已經先發表過 fastText 了,在這個月的月初又發表了另外一個演算法 Misspelling Oblivious Embeddings (MOE),是搭著本來的 fastText 而得到的改善:「A new model for word embeddings that are resilient to misspellings」。

Facebook 的說明提到在 user-generated text 的內容上,MOE 的效果比 fastText 好:

We checked the effectiveness of this approach considering different intrinsic and extrinsic tasks, and found that MOE outperforms fastText for user-generated text.

論文發表在 arXiv 上:「Misspelling Oblivious Word Embeddings」。

依照介紹,fastText 的重點在於 semantic loss,而 MOE 則多了 spell correction loss:

The loss function of fastText aims to more closely embed words that occur in the same context. We call this semantic loss. In addition to the semantic loss, MOE also considers an additional supervisedloss that we call spell correction loss. The spell correction loss aims to embed misspellings close to their correct versions by minimizing the weighted sum of semantic loss and spell correction loss.

不過目前 GitHub 上的 facebookresearch/moe 只有放 dataset,沒有 open source 出來讓人直接用,可能得自己刻...

讓 Laravel 的 PHPUnit 在發生錯誤時把 Stack 丟出來

這兩天又遇到一次,這應該是 Laravel 裡設計比較奇怪的地方,既然是跑 PHPUnit 的環境,為什麼不預設在錯誤發生時把完整的 stack 拋到 console...

這邊的解法是參考「Laravel: How to enable stacktrace error on PhpUnit」這篇的解答。

舊版需要自己丟 handler 進去 (5.4 以及之前的版本),在 5.5+ (寫這篇時最新的穩定版本已經是 5.6) 有內建 withoutExceptionHandling() 可以用,所以在 tests/TestCase.php 內搞定 setUp()

    protected function setUp()
    {
        parent::setUp();
        $this->withoutExceptionHandling();
    }

不知道有沒有機會直接進 Laravel 的 package 設定裡面...

MySQL 版本的 Amazon Aurora 會將各種記錄丟到 CloudWatch Logs 了...

剛好今天才被問是不是可以在 Amazon Aurora (MySQL-Compatible Edition) 裡面翻出有哪些 Slow Query,剛好想到這幾天發表了這個功能:「Amazon Aurora Publishes General, Slow Query and Error Logs to Amazon CloudWatch」。

You can now configure the MySQL-compatible edition of Amazon Aurora to publish general logs, slow query logs, and error logs to Amazon CloudWatch Logs. Previously, you could only publish audit logs.

看起來是要另外開 (畢竟 CloudWatch Logs 不是免費的 XD),不過以這類型的 log 產生速度與數量來說應該還行...

Trac 1.2 上惡搞 TracTicketReferencePlugin 讓他會動...

TracTicketReferencePlugin 是個 Trac 上設定 ticket 之間關聯性的 plugin,與子母票有比較強烈的關係不同,有些人喜歡把相關的資料都掛在這邊。先前用都是在 Trac 1.0 上用,也沒什麼問題,最近在 Trac 1.2 上跑發現直接有 js error...

原因是 TracTicketReferencePlugin 用到 jQuery.live(),而這個函式在 jQuery 1.7 被宣告 deprecated,在 jQuery 1.9 被正式拔掉了。而 Trac 1.0 用的是 jQuery 1.7,所以不會有問題;Trac 1.2 用的是 jQuery 1.12,於是就爛掉了...

剛好就是昨天,有人在作者的 repository 上發 issue 出來 (另外也提供了 patch):「t2y / trac.plugins.ticketref / issues / #9 - JavaScript errors with Trac 1.2 — Bitbucket」。雖然 patch 本身不算難,但我實在懶的查 Mercurial 的操作,於是決定用 workaround 解...

想法是讓 jQuery.live() 會動,這點在 jQuery 官方出的 Migrate 就可以達到 (需要用 1.4.1 版,而不是 3.0.1 版),於是第一步就是在 site.html 內直接先下手為強,讀 jQuery 後馬上讀 Migrate:

  <!--! Add site-specific style sheet -->
  <head py:match="head" py:attrs="select('@*')">
    <script src="https://code.jquery.com/jquery-1.12.4.min.js"></script>
    <script src="https://code.jquery.com/jquery-migrate-1.4.1.min.js"></script>
    ${select('*|comment()|text()')}

但 Trac 還是會再載入一次的 jQuery 而蓋過去,所以我們要讓 Trac 不會載入,在 trac.ini 內的 jquery_location 設定讓他讀一個空的 js 檔:

jquery_location = site/null.js

然後生一個空的 trac/htdocs/null.js 讓他讀。

最後開一張票追蹤,看什麼時候官方放新版,再把這串 workaround 拔掉...