<?xml version="1.0" encoding="utf-8"?>






<rss xmlns:atom="http://www.w3.org/2005/Atom" version="2.0">
    <channel>
        <title>Chienlung&#39;s Blog</title>
        <link>https://blog.momonga.dev/</link>
        <description>This is Chienlung&#39;s personal blog.</description>
        <generator>Hugo 0.147.7 https://gohugo.io/</generator>
        
            <language>zh-TW</language>
        
        
        
        
            <copyright>[CC BY-NC-SA 4.0](https://creativecommons.org/licenses/by-nc-sa/4.0/deed.en)</copyright>
        
        <lastBuildDate>Thu, 27 Aug 2026 17:35:44 &#43;0000</lastBuildDate>
        
            <atom:link rel="self" type="application/rss&#43;xml" href="https://blog.momonga.dev/rss.xml" />
        
        
            <item>
                <title>Sentry Issue 匯出工具</title>
                <link>https://blog.momonga.dev/posts/export-sentry-issue/</link>
                <guid isPermaLink="true">https://blog.momonga.dev/posts/export-sentry-issue/</guid>
                <pubDate>Mon, 06 Oct 2025 15:19:37 &#43;0800</pubDate>
                
                <copyright>[CC BY-NC-SA 4.0](https://creativecommons.org/licenses/by-nc-sa/4.0/deed.en)</copyright>
                
                
                <description>
                        &lt;p&gt;週末期間用 Claude Code vibe coding 了一套可以將 Sentry issue 匯出成純文字的工具：&lt;a href=&#34;https://github.com/jlhg/export-sentry-issue&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;export-sentry-issue&lt;/a&gt;，採 MIT 授權，同步發佈到 PyPI，順便做了 MCP 串接。只要告訴 Claude 你想要請他 review Sentry issue #編號，他就會自動幫你下載及分析 Sentry issue，加速除錯，相當方便。&lt;/p&gt;
&lt;p&gt;隨著 AI 工具的日益成熟，從一開始只使用網頁版問答、到使用命令列工具直接的參與程式碼修改，工程師的角色已從 coder 變成 reviewer。在審查程式碼的過程中，可以發現新的問題，也可以學到新的知識。AI 不僅僅是協助完成工作，也可以協助思考。在 Docker 之後，我認為 AI Programming Assistant 已是工程師必備技能之一。&lt;/p&gt;

                        
                    </description>
                
                
                
                
                
                    
                        
                            
                                
                                
                                
                                    <category domain="https://blog.momonga.dev/categories/software-development/">Software Development</category>
                                
                            
                        
                    
                        
                            
                                
                                
                                
                                    <category domain="https://blog.momonga.dev/tags/claude/">Claude</category>
                                
                            
                                
                                
                                
                                    <category domain="https://blog.momonga.dev/tags/sentry/">Sentry</category>
                                
                            
                                
                                
                                
                                    <category domain="https://blog.momonga.dev/tags/python/">Python</category>
                                
                            
                                
                                
                                
                                    <category domain="https://blog.momonga.dev/tags/mcp/">MCP</category>
                                
                            
                        
                    
                
            </item>
        
            <item>
                <title>[AI 中文摘要] On | No syntactic support for error handling</title>
                <link>https://blog.momonga.dev/posts/summarize-go-error-syntax/</link>
                <guid isPermaLink="true">https://blog.momonga.dev/posts/summarize-go-error-syntax/</guid>
                <pubDate>Wed, 04 Jun 2025 11:04:35 &#43;0800</pubDate>
                
                <copyright>[CC BY-NC-SA 4.0](https://creativecommons.org/licenses/by-nc-sa/4.0/deed.en)</copyright>
                
                
                <description>
                        &lt;p&gt;本文為 AI 中文摘要，原始文章：&lt;a href=&#34;https://go.dev/blog/error-syntax&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;[ On | No ] syntactic support for error handling - The Go Programming Language&lt;/a&gt;&lt;/p&gt;
&lt;hr&gt;
&lt;p&gt;&lt;strong&gt;文章摘要：Go 語言錯誤處理語法支援的探討與結論&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;日期：&lt;/strong&gt; 2025年6月3日&lt;br&gt;
&lt;strong&gt;作者：&lt;/strong&gt; Robert Griesemer&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;1. 前言：Go 語言錯誤處理的冗餘性問題&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Go 語言中常見的錯誤處理模式，即 &lt;code&gt;if err != nil&lt;/code&gt; 檢查，長期以來因其冗餘 (verbosity) 而備受詬病。在大量進行 API 呼叫或錯誤處理相對單純（僅向上回傳）的程式中，此模式會淹沒主要邏輯程式碼。例如，一個簡單的 &lt;code&gt;printSum&lt;/code&gt; 函數，其十行程式碼中，有六行專用於錯誤檢查與回傳，僅四行執行實際運算。此問題在年度使用者調查中持續名列前茅（僅次於泛型 (generics) 問題，在泛型支援後重回首位）。Go 團隊對此高度重視，並多年來持續尋求解決方案。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;2. Go 團隊在錯誤處理語法上的歷史性嘗試&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Go 團隊針對錯誤處理的冗餘問題，進行了多次重要的語法改進嘗試：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;2.1. &lt;code&gt;check&lt;/code&gt; 與 &lt;code&gt;handle&lt;/code&gt; 機制 (2018年)&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;由 Russ Cox 正式提出，基於 Marcel van Lohuizen 的草案設計。&lt;/li&gt;
&lt;li&gt;該機制引入了 &lt;code&gt;check&lt;/code&gt; 關鍵字用於檢查錯誤，&lt;code&gt;handle&lt;/code&gt; 區塊用於定義錯誤處理邏輯。&lt;/li&gt;
&lt;li&gt;範例：
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-go&#34; data-lang=&#34;go&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;kd&#34;&gt;func&lt;/span&gt; &lt;span class=&#34;nf&#34;&gt;printSum&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;a&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;b&lt;/span&gt; &lt;span class=&#34;kt&#34;&gt;string&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;kt&#34;&gt;error&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;nx&#34;&gt;handle&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;err&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt; &lt;span class=&#34;k&#34;&gt;return&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;err&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;}&lt;/span&gt; &lt;span class=&#34;c1&#34;&gt;// 定義錯誤處理方式&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;nx&#34;&gt;x&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;:=&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;check&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;strconv&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nf&#34;&gt;Atoi&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;a&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;c1&#34;&gt;// 若 strconv.Atoi(a) 回傳錯誤，則執行 handle 區塊&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;nx&#34;&gt;y&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;:=&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;check&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;strconv&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nf&#34;&gt;Atoi&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;b&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;c1&#34;&gt;// 同上&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;nx&#34;&gt;fmt&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nf&#34;&gt;Println&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&amp;#34;result:&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;x&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;+&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;y&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;k&#34;&gt;return&lt;/span&gt; &lt;span class=&#34;kc&#34;&gt;nil&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/li&gt;
&lt;li&gt;此提案因被認為過於複雜而未被採納。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;2.2. &lt;code&gt;try&lt;/code&gt; 內建函數提案 (2019年)&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;作為 &lt;code&gt;check/handle&lt;/code&gt; 的簡化版，&lt;code&gt;try&lt;/code&gt; 是一個內建函數 (built-in function)，若其參數表達式回傳錯誤，&lt;code&gt;try&lt;/code&gt; 會使當前函數立即回傳該錯誤。&lt;/li&gt;
&lt;li&gt;為評估影響，團隊開發了 &lt;code&gt;tryhard&lt;/code&gt; 工具將現有程式碼轉換為使用 &lt;code&gt;try&lt;/code&gt;。&lt;/li&gt;
&lt;li&gt;範例：
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-go&#34; data-lang=&#34;go&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;kd&#34;&gt;func&lt;/span&gt; &lt;span class=&#34;nf&#34;&gt;printSum&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;a&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;b&lt;/span&gt; &lt;span class=&#34;kt&#34;&gt;string&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;kt&#34;&gt;error&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;nx&#34;&gt;x&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;:=&lt;/span&gt; &lt;span class=&#34;nf&#34;&gt;try&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;strconv&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nf&#34;&gt;Atoi&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;a&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;))&lt;/span&gt; &lt;span class=&#34;c1&#34;&gt;// 若 strconv.Atoi(a) 回傳錯誤，printSum 將回傳該錯誤&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;nx&#34;&gt;y&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;:=&lt;/span&gt; &lt;span class=&#34;nf&#34;&gt;try&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;strconv&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nf&#34;&gt;Atoi&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;b&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;))&lt;/span&gt; &lt;span class=&#34;c1&#34;&gt;// 同上&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;nx&#34;&gt;fmt&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nf&#34;&gt;Println&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&amp;#34;result:&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;x&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;+&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;y&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;k&#34;&gt;return&lt;/span&gt; &lt;span class=&#34;kc&#34;&gt;nil&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/li&gt;
&lt;li&gt;此提案因其隱含的控制流程 (control flow) 改變（可能從深層巢狀表達式中提前返回）而引發爭議，最終被放棄。&lt;/li&gt;
&lt;li&gt;事後反思，引入新關鍵字而非內建函數，並限制其使用範圍，或許是更佳的途徑。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;2.3. &lt;code&gt;?&lt;/code&gt; 運算子提案 (2024年)&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;由 Ian Lance Taylor 提出，借鏡 Rust 語言的 &lt;code&gt;?&lt;/code&gt; 運算子。&lt;/li&gt;
&lt;li&gt;期望藉由參考已建立的機制與符號來取得進展。&lt;/li&gt;
&lt;li&gt;非正式使用者研究顯示，多數開發者能正確理解 &lt;code&gt;?&lt;/code&gt; 的含義。&lt;/li&gt;
&lt;li&gt;團隊開發了轉換工具並在編譯器中原型化了此功能。&lt;/li&gt;
&lt;li&gt;範例：
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-go&#34; data-lang=&#34;go&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;kd&#34;&gt;func&lt;/span&gt; &lt;span class=&#34;nf&#34;&gt;printSum&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;a&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;b&lt;/span&gt; &lt;span class=&#34;kt&#34;&gt;string&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;kt&#34;&gt;error&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;nx&#34;&gt;x&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;:=&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;strconv&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nf&#34;&gt;Atoi&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;a&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;err&#34;&gt;?&lt;/span&gt; &lt;span class=&#34;c1&#34;&gt;// 若 strconv.Atoi(a) 回傳錯誤，printSum 將回傳該錯誤&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;nx&#34;&gt;y&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;:=&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;strconv&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nf&#34;&gt;Atoi&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;b&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;err&#34;&gt;?&lt;/span&gt; &lt;span class=&#34;c1&#34;&gt;// 同上&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;nx&#34;&gt;fmt&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nf&#34;&gt;Println&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&amp;#34;result:&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;x&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;+&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;y&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;k&#34;&gt;return&lt;/span&gt; &lt;span class=&#34;kc&#34;&gt;nil&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/li&gt;
&lt;li&gt;此提案同樣迅速引發大量討論與基於個人偏好的微調建議，未能獲得廣泛支持，最終提案被關閉並轉為討論。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;3. 社群的持續參與及提案過程的反思&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;在 Go 團隊嘗試的同時，社群也湧現了大量錯誤處理提案（數以百計），多數為既有概念的變體。Ian Lance Taylor 為此創建了追蹤議題 (umbrella issue) 及 Go Wiki 頁面以彙整相關資訊。&lt;/p&gt;
&lt;p&gt;&lt;code&gt;try&lt;/code&gt; 提案的失敗促使團隊反思提案流程，Russ Cox 的系列部落格文章指出，過早提出近乎完整的提案並設定緊迫的實施時程，可能減少了社群反饋的空間，影響了結果。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;4. Go 團隊的最終決定：暫停追求語法層面的解決方案&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;歷經多年、多次官方及大量社群提案均未能達成共識後，Go 團隊決定：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;在可預見的未來，停止追求針對錯誤處理的語法層級語言變更 (syntactic language changes)。&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;關閉所有主要涉及錯誤處理語法的現有及未來提案，不再進一步調查。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;此決定的依據是 Go 的提案流程 (proposal process) 要求達成普遍共識 (general consensus)，而所有錯誤處理提案均未達到此標準。即使是 Go 團隊資深成員內部，目前也未對最佳方案有一致看法。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;5. 維持現狀 (Status Quo) 的論點&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;支持維持當前錯誤處理方式的論點包括：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;時機已過：&lt;/strong&gt; Go 已發展15年，儘管冗餘，但現有的錯誤處理方式運作良好。若早期引入語法糖 (syntactic sugar)，爭議可能較小。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;避免新的分歧：&lt;/strong&gt; 引入新語法會使一部分偏好現狀的使用者不滿。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;與泛型的差異：&lt;/strong&gt; 泛型是可選的，而新的錯誤處理語法幾乎會要求所有人都採用，以維持程式碼的慣用風格 (idiomatic)。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Go 設計原則：&lt;/strong&gt; 避免為同一件事提供多種做法。
&lt;ul&gt;
&lt;li&gt;諷刺的是，短變數宣告 (short variable declarations) &lt;code&gt;:=&lt;/code&gt; 中的變數重宣告 (redeclaration) 功能，部分是為了解決錯誤檢查序列中 &lt;code&gt;err&lt;/code&gt; 變數命名問題而引入。若有更好的錯誤處理語法，此規則或可避免。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;實際錯誤處理的影響：&lt;/strong&gt; 當錯誤被「實際處理」（例如，使用 &lt;code&gt;fmt.Errorf&lt;/code&gt; 添加上下文信息）時，樣板程式碼 (boilerplate) 的相對比例會降低。
&lt;ul&gt;
&lt;li&gt;範例：
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-go&#34; data-lang=&#34;go&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;kd&#34;&gt;func&lt;/span&gt; &lt;span class=&#34;nf&#34;&gt;printSum&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;a&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;b&lt;/span&gt; &lt;span class=&#34;kt&#34;&gt;string&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;kt&#34;&gt;error&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;nx&#34;&gt;x&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;err&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;:=&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;strconv&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nf&#34;&gt;Atoi&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;a&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;k&#34;&gt;if&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;err&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;!=&lt;/span&gt; &lt;span class=&#34;kc&#34;&gt;nil&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;k&#34;&gt;return&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;fmt&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nf&#34;&gt;Errorf&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&amp;#34;invalid integer: %q&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;a&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;c1&#34;&gt;// 錯誤被包裝&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;c1&#34;&gt;// ...&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;標準庫的輔助：&lt;/strong&gt; 新的標準庫功能（如 &lt;code&gt;cmp.Or&lt;/code&gt;）可以幫助減少樣板。
&lt;ul&gt;
&lt;li&gt;範例：
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-go&#34; data-lang=&#34;go&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;kd&#34;&gt;func&lt;/span&gt; &lt;span class=&#34;nf&#34;&gt;printSum&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;a&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;b&lt;/span&gt; &lt;span class=&#34;kt&#34;&gt;string&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;kt&#34;&gt;error&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;nx&#34;&gt;x&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;err1&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;:=&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;strconv&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nf&#34;&gt;Atoi&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;a&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;nx&#34;&gt;y&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;err2&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;:=&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;strconv&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nf&#34;&gt;Atoi&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;b&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;k&#34;&gt;if&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;err&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;:=&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;cmp&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nf&#34;&gt;Or&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;err1&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;err2&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;err&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;!=&lt;/span&gt; &lt;span class=&#34;kc&#34;&gt;nil&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt; &lt;span class=&#34;c1&#34;&gt;// 一次處理多個錯誤&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;k&#34;&gt;return&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;err&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;c1&#34;&gt;// ...&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;工具的輔助：&lt;/strong&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;撰寫：&lt;/strong&gt; IDE 和 LLM 輔助的程式碼完成 (code completion) 可簡化重複錯誤檢查的撰寫。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;閱讀：&lt;/strong&gt; IDE 或可提供開關以隱藏錯誤處理程式碼。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;除錯 (Debugging)：&lt;/strong&gt; 明確的 &lt;code&gt;if&lt;/code&gt; 陳述式更易於設定中斷點 (breakpoint) 或添加調試輸出，而隱藏在 &lt;code&gt;check&lt;/code&gt;、&lt;code&gt;try&lt;/code&gt; 或 &lt;code&gt;?&lt;/code&gt; 後的邏輯則需先轉換回 &lt;code&gt;if&lt;/code&gt; 形式。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;實際成本考量：&lt;/strong&gt; 語言變更成本高昂（設計、實施、文件更新、工具調整），而 Go 團隊資源有限，尚有其他優先事項。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;部分使用者反饋：&lt;/strong&gt; 在 Google Cloud Next 2025 等場合，部分 Go 使用者明確表示不希望改變現有錯誤處理方式，並認為隨着對 Go 的熟練度增加，此問題的重要性會降低。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;6. 支持變革的論點（雖未被採納）&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;儘管決定不進行語法變更，但支持變革的論點依然存在：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;使用者調查中，錯誤處理冗餘仍是首要抱怨。&lt;/li&gt;
&lt;li&gt;關注點或許不應僅是減少字元數，而是透過關鍵字等方式提高預設錯誤處理的可見性，進而提升程式碼品質與安全性。&lt;/li&gt;
&lt;li&gt;目前尚不完全清楚問題的核心是語法冗餘，還是良好錯誤處理（建構對開發者和終端使用者都有意義的錯誤）本身的複雜性。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;7. 結論與未來展望&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;鑑於對問題本身及其是否存在缺乏共識，Go 團隊做出務實決定：在可預見的未來停止追求錯誤處理的語法層級語言變更。團隊感謝社群在探討此議題上的巨大投入，這些努力雖未直接改變錯誤處理語法，但也促成了 Go 語言及流程上的其他改進。團隊期望將這份熱情投入到新的機會，使 Go 對所有人更好，並期待未來或許會對錯誤處理問題有更清晰的認識。&lt;/p&gt;
                        
                    </description>
                
                
                
                
                
                    
                        
                            
                                
                                
                                
                                    <category domain="https://blog.momonga.dev/categories/software-development/">Software Development</category>
                                
                            
                        
                    
                        
                            
                                
                                
                                
                                    <category domain="https://blog.momonga.dev/tags/go/">Go</category>
                                
                            
                        
                    
                
            </item>
        
            <item>
                <title>修復 iPhone SE2 白屏死機畫面</title>
                <link>https://blog.momonga.dev/posts/fix-iphone-se-blank-screen/</link>
                <guid isPermaLink="true">https://blog.momonga.dev/posts/fix-iphone-se-blank-screen/</guid>
                <pubDate>Sun, 28 Apr 2024 00:08:44 &#43;0800</pubDate>
                
                <copyright>[CC BY-NC-SA 4.0](https://creativecommons.org/licenses/by-nc-sa/4.0/deed.en)</copyright>
                
                
                <description>
                        &lt;p&gt;iPhone SE2 (iOS 17.4.1) 不明原因出現白屏死機畫面，嘗試過按住側邊按鈕、同時按住側邊按鈕及主畫面按鈕都沒辦法叫出關機滑桿。照著 &lt;a href=&#34;https://support.apple.com/zh-tw/116940&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;Apple 官方教學&lt;/a&gt;執行以下步驟，結果有用，成功救了一台 iPhone。&lt;/p&gt;
&lt;blockquote&gt;
&lt;ol&gt;
&lt;li&gt;按下調高音量按鈕後迅速放開。&lt;/li&gt;
&lt;li&gt;按下調低音量按鈕後迅速放開。&lt;/li&gt;
&lt;li&gt;按住側邊按鈕，直到看到 Apple 標誌為止（大約 10 秒鐘）。&lt;/li&gt;
&lt;/ol&gt;&lt;/blockquote&gt;
&lt;p&gt;這個方法有用但冷門，一般使用 PC 的習慣，直覺會想到按住一個按鈕或同時按住兩個按鈕。至於有的網站說可以下載修復工具之類的軟體，這倒是可以建議一個都不要嘗試。&lt;/p&gt;

                        
                    </description>
                
                
                
                
                
                    
                        
                            
                                
                                
                                
                                    <category domain="https://blog.momonga.dev/categories/hardware/">Hardware</category>
                                
                            
                        
                    
                        
                            
                                
                                
                                
                                    <category domain="https://blog.momonga.dev/tags/iphone/">IPhone</category>
                                
                            
                                
                                
                                
                                    <category domain="https://blog.momonga.dev/tags/recovery/">Recovery</category>
                                
                            
                        
                    
                
            </item>
        
            <item>
                <title>Firefox 的 Caret Browsing</title>
                <link>https://blog.momonga.dev/posts/firefox-caret-browsing/</link>
                <guid isPermaLink="true">https://blog.momonga.dev/posts/firefox-caret-browsing/</guid>
                <pubDate>Sat, 20 Apr 2024 06:11:31 &#43;0800</pubDate>
                
                <copyright>[CC BY-NC-SA 4.0](https://creativecommons.org/licenses/by-nc-sa/4.0/deed.en)</copyright>
                
                
                <description>
                        &lt;p&gt;最近發現瀏覽 Firefox 頁面時，滑鼠點擊頁面的任何位置都會出現游標，本來以為是某個更新版本出現的 bug，但覺得也過太久沒有修正了。於是搜尋是否有人回報這個問題，&lt;a href=&#34;https://support.mozilla.org/en-US/questions/970659&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;找到這篇&lt;/a&gt;，原來是我不小心啟動了&lt;a href=&#34;https://support.mozilla.org/zh-TW/kb/accessibility-features-firefox-make-firefox-and-we#w_shi-yong-jian-pan-cao-zuo&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;文字游標瀏覽 (Caret Browsing)&lt;/a&gt; 功能。該功能的熱鍵是 &lt;code&gt;F7&lt;/code&gt;，點擊 &lt;code&gt;F7&lt;/code&gt; 之後就可以關閉這項功能。&lt;/p&gt;
&lt;p&gt;Caret Browsing 是無障礙功能之一，目的是使用鍵盤操作，但我覺得沒有很好用。純鍵盤瀏覽網頁，我會推薦使用 &lt;a href=&#34;https://github.com/philc/vimium&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;Vimium&lt;/a&gt; 擴充套件。&lt;/p&gt;

                        
                    </description>
                
                
                
                
                
                    
                        
                            
                                
                                
                                
                                    <category domain="https://blog.momonga.dev/categories/config/">Config</category>
                                
                            
                        
                    
                        
                            
                                
                                
                                
                                    <category domain="https://blog.momonga.dev/tags/firefox/">Firefox</category>
                                
                            
                                
                                
                                
                                    <category domain="https://blog.momonga.dev/tags/caret-browsing/">Caret Browsing</category>
                                
                            
                                
                                
                                
                                    <category domain="https://blog.momonga.dev/tags/%E7%84%A1%E9%9A%9C%E7%A4%99/">無障礙</category>
                                
                            
                        
                    
                
            </item>
        
            <item>
                <title>解決 rb-inotify 的 Permission Denied 錯誤</title>
                <link>https://blog.momonga.dev/posts/fix-inotify-permission-error-on-rails/</link>
                <guid isPermaLink="true">https://blog.momonga.dev/posts/fix-inotify-permission-error-on-rails/</guid>
                <pubDate>Fri, 12 Apr 2024 07:36:35 &#43;0800</pubDate>
                
                <copyright>[CC BY-NC-SA 4.0](https://creativecommons.org/licenses/by-nc-sa/4.0/deed.en)</copyright>
                
                
                <description>
                        &lt;p&gt;在開發 Ruby on Rails 網站時，使用 &lt;code&gt;rails g controller&lt;/code&gt; 指令新增 controller 時，出現一個錯誤：&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-txt&#34; data-lang=&#34;txt&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;/home/**/.rbenv/versions/2.6.10/lib/ruby/gems/2.6.0/gems/rb-inotify-0.10.1/lib/rb-inotify/notifier.rb:200:in `initialize&amp;#39;: Permission denied @ dir_initialize - /home/**/**/srv/pg (Errno::EACCES)
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;原因是 rb-inotify 掃描專案根目錄下的 &lt;code&gt;srv/pg&lt;/code&gt; 資料夾時遇到存取權限問題。該資料夾是用 PostgreSQL docker container 建立的，只有 root 才有讀取權限。&lt;/p&gt;
&lt;p&gt;我想知道能不能設定 rb-inotify ，將 &lt;code&gt;srv/pg&lt;/code&gt; 加入例外清單，但發現無法，且作者似乎也不打算處理 &lt;sup id=&#34;fnref:1&#34;&gt;&lt;a href=&#34;https://blog.momonga.dev/posts/fix-inotify-permission-error-on-rails/#fn:1&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;[1]&lt;/a&gt;&lt;/sup&gt;&lt;sup id=&#34;fnref:2&#34;&gt;&lt;a href=&#34;https://blog.momonga.dev/posts/fix-inotify-permission-error-on-rails/#fn:2&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;[2]&lt;/a&gt;&lt;/sup&gt;。最後&lt;a href=&#34;https://github.com/rails/spring-watcher-listen/issues/15#issuecomment-909113142&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;找到解法&lt;/a&gt;，在 &lt;code&gt;config/sprint.rb&lt;/code&gt; 原本的內容上方加入以下程式碼，改寫原本的 &lt;code&gt;watch&lt;/code&gt; 方法：&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-rb&#34; data-lang=&#34;rb&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;no&#34;&gt;INOTIFY_BLACKLIST&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;[&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;s2&#34;&gt;&amp;#34;.git&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;s2&#34;&gt;&amp;#34;node_modules&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;s2&#34;&gt;&amp;#34;tmp&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;s2&#34;&gt;&amp;#34;log&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;s2&#34;&gt;&amp;#34;srv&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;o&#34;&gt;].&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;map&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;|&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;dir&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;|&lt;/span&gt; &lt;span class=&#34;no&#34;&gt;Pathname&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;no&#34;&gt;Spring&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;watcher&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;root&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;glob&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;dir&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;flatten&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;map&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&#34;ss&#34;&gt;:to_s&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nb&#34;&gt;require&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;rb-inotify&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;k&#34;&gt;module&lt;/span&gt; &lt;span class=&#34;nn&#34;&gt;INotifyNotifierIgnorer&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;k&#34;&gt;def&lt;/span&gt; &lt;span class=&#34;nf&#34;&gt;watch&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;path&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;*&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;flags&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;callback&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;k&#34;&gt;return&lt;/span&gt; &lt;span class=&#34;k&#34;&gt;if&lt;/span&gt; &lt;span class=&#34;no&#34;&gt;INOTIFY_BLACKLIST&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;include?&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;path&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;c1&#34;&gt;# warn path # to see all the paths listened to&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;k&#34;&gt;super&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;path&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;*&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;flags&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;callback&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;k&#34;&gt;end&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;k&#34;&gt;end&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;no&#34;&gt;INotify&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;::&lt;/span&gt;&lt;span class=&#34;no&#34;&gt;Notifier&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;prepend&lt;/span&gt; &lt;span class=&#34;no&#34;&gt;INotifyNotifierIgnorer&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;div class=&#34;footnotes&#34; role=&#34;doc-endnotes&#34;&gt;
&lt;ol&gt;
&lt;li id=&#34;fn:1&#34;&gt;
&lt;p&gt;&lt;a href=&#34;https://stackoverflow.com/questions/51953429/permissions-denied-with-the-docker-volumes-folder-when-using-rails-cli/56258384#56258384&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;linux - Permissions denied with the docker volumes folder when using rails CLI - Stack Overflow&lt;/a&gt;&amp;#160;&lt;a href=&#34;https://blog.momonga.dev/posts/fix-inotify-permission-error-on-rails/#fnref:1&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&lt;svg xmlns=&#34;http://www.w3.org/2000/svg&#34; viewBox=&#34;0 0 320 512&#34; class=&#34;icon footnote-icon&#34;&gt;&lt;path d=&#34;M177 159.7l136 136c9.4 9.4 9.4 24.6 0 33.9l-22.6 22.6c-9.4 9.4-24.6 9.4-33.9 0L160 255.9l-96.4 96.4c-9.4 9.4-24.6 9.4-33.9 0L7 329.7c-9.4-9.4-9.4-24.6 0-33.9l136-136c9.4-9.5 24.6-9.5 34-.1z&#34;/&gt;&lt;/svg&gt;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&#34;fn:2&#34;&gt;
&lt;p&gt;&lt;a href=&#34;https://github.com/guard/rb-inotify/issues/48&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;Ability to exclude certain files when using recursive watch · Issue #48 · guard/rb-inotify&lt;/a&gt;&amp;#160;&lt;a href=&#34;https://blog.momonga.dev/posts/fix-inotify-permission-error-on-rails/#fnref:2&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&lt;svg xmlns=&#34;http://www.w3.org/2000/svg&#34; viewBox=&#34;0 0 320 512&#34; class=&#34;icon footnote-icon&#34;&gt;&lt;path d=&#34;M177 159.7l136 136c9.4 9.4 9.4 24.6 0 33.9l-22.6 22.6c-9.4 9.4-24.6 9.4-33.9 0L160 255.9l-96.4 96.4c-9.4 9.4-24.6 9.4-33.9 0L7 329.7c-9.4-9.4-9.4-24.6 0-33.9l136-136c9.4-9.5 24.6-9.5 34-.1z&#34;/&gt;&lt;/svg&gt;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;/div&gt;
                        
                    </description>
                
                
                
                
                
                    
                        
                            
                                
                                
                                
                                    <category domain="https://blog.momonga.dev/categories/software-development/">Software Development</category>
                                
                            
                        
                    
                        
                            
                                
                                
                                
                                    <category domain="https://blog.momonga.dev/tags/ruby/">Ruby</category>
                                
                            
                                
                                
                                
                                    <category domain="https://blog.momonga.dev/tags/ruby-on-rails/">Ruby on Rails</category>
                                
                            
                                
                                
                                
                                    <category domain="https://blog.momonga.dev/tags/docker/">Docker</category>
                                
                            
                        
                    
                
            </item>
        
            <item>
                <title>Windows Terminal 支援 Font Fallback</title>
                <link>https://blog.momonga.dev/posts/windows-terminal-supports-font-fallback/</link>
                <guid isPermaLink="true">https://blog.momonga.dev/posts/windows-terminal-supports-font-fallback/</guid>
                <pubDate>Thu, 11 Apr 2024 01:13:16 &#43;0800</pubDate>
                
                <copyright>[CC BY-NC-SA 4.0](https://creativecommons.org/licenses/by-nc-sa/4.0/deed.en)</copyright>
                
                
                <description>
                        &lt;p&gt;最近在研究 Windows Terminal 有沒有什麼方法可以顯示自訂中文字型，但英文仍保留等寬字型 (monospace)。在 &lt;a href=&#34;https://github.com/microsoft/terminal/issues/2664&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;GitHub Issue&lt;/a&gt; 看到最近&lt;a href=&#34;https://github.com/microsoft/terminal/pull/16821&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;已經有人實作 font fallback 功能&lt;/a&gt;並合併到主分支裡面了，但尚未釋出到穩定版。要使用這功能，可以下載 &lt;a href=&#34;https://github.com/microsoft/terminal?tab=readme-ov-file#installing-windows-terminal-canary&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;Windows Terminal Canary&lt;/a&gt;，這是 Windows Terminal 的 Nightly build 版本。安裝後打開設定 JSON 檔案，找到 font ➔ face key，改成跟 CSS font-family 一樣的格式就可以。&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-json&#34; data-lang=&#34;json&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;nt&#34;&gt;&amp;#34;font&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;nt&#34;&gt;&amp;#34;face&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;&amp;#39;DejaVuSansM Nerd Font Mono&amp;#39;, &amp;#39;Noto Sans CJK TC&amp;#39;&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
                        
                    </description>
                
                
                
                
                
                    
                        
                            
                                
                                
                                
                                    <category domain="https://blog.momonga.dev/categories/config/">Config</category>
                                
                            
                        
                    
                        
                            
                                
                                
                                
                                    <category domain="https://blog.momonga.dev/tags/windows-terminal/">Windows Terminal</category>
                                
                            
                                
                                
                                
                                    <category domain="https://blog.momonga.dev/tags/font-fallback/">Font Fallback</category>
                                
                            
                        
                    
                
            </item>
        
            <item>
                <title>HSTS vs HTTPS-Only Mode</title>
                <link>https://blog.momonga.dev/posts/hsts-vs-https-only-mode/</link>
                <guid isPermaLink="true">https://blog.momonga.dev/posts/hsts-vs-https-only-mode/</guid>
                <pubDate>Wed, 06 Dec 2023 01:27:59 &#43;0800</pubDate>
                
                <copyright>[CC BY-NC-SA 4.0](https://creativecommons.org/licenses/by-nc-sa/4.0/deed.en)</copyright>
                
                
                <description>
                        &lt;p&gt;近年來主流的瀏覽器陸續支援 HTTPS-Only Mode&lt;sup id=&#34;fnref:1&#34;&gt;&lt;a href=&#34;https://blog.momonga.dev/posts/hsts-vs-https-only-mode/#fn:1&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;[1]&lt;/a&gt;&lt;/sup&gt;&lt;sup id=&#34;fnref:2&#34;&gt;&lt;a href=&#34;https://blog.momonga.dev/posts/hsts-vs-https-only-mode/#fn:2&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;[2]&lt;/a&gt;&lt;/sup&gt;&lt;sup id=&#34;fnref:3&#34;&gt;&lt;a href=&#34;https://blog.momonga.dev/posts/hsts-vs-https-only-mode/#fn:3&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;[3]&lt;/a&gt;&lt;/sup&gt;。該模式啟用時，使用者造訪任何網站，瀏覽器都會優先選用 HTTPS。&lt;/p&gt;
&lt;p&gt;HTTP Strict Transport Security (HSTS) 是一個網路安全機制，透過伺服器的回應帶有 Strict-Transport-Security 標頭，強制瀏覽器只能使用 HTTPS 傳輸。&lt;/p&gt;
&lt;p&gt;這兩者有何差別呢？ Mozilla Blog 有一篇文章&lt;sup id=&#34;fnref:4&#34;&gt;&lt;a href=&#34;https://blog.momonga.dev/posts/hsts-vs-https-only-mode/#fn:4&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;[4]&lt;/a&gt;&lt;/sup&gt;的圖文解說相當清楚。簡單的說，HTTPS-Only Mode 可以確保使用者訪問網站送出的第一個請求是 HTTPS。當網站不支援 HTTPS 時，會跳出警告讓使用者選擇是否改以 HTTP 訪問。HSTS 的機制則是做到完全的禁止使用者以 HTTP 訪問，但前提是使用者必須先以 HTTPS 進行請求，才會收到 Strict-Transport-Security 標頭。HSTS 無法確保使用者訪問網站時送出的第一個請求為 HTTPS，首次連線很容易面臨中間人攻擊的風險。&lt;/p&gt;
&lt;div class=&#34;footnotes&#34; role=&#34;doc-endnotes&#34;&gt;
&lt;ol&gt;
&lt;li id=&#34;fn:1&#34;&gt;
&lt;p&gt;&lt;a href=&#34;https://www.ithome.com.tw/news/145426&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;Chrome瀏覽器即將具備HTTPS-Only模式 | iThome&lt;/a&gt;&amp;#160;&lt;a href=&#34;https://blog.momonga.dev/posts/hsts-vs-https-only-mode/#fnref:1&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&lt;svg xmlns=&#34;http://www.w3.org/2000/svg&#34; viewBox=&#34;0 0 320 512&#34; class=&#34;icon footnote-icon&#34;&gt;&lt;path d=&#34;M177 159.7l136 136c9.4 9.4 9.4 24.6 0 33.9l-22.6 22.6c-9.4 9.4-24.6 9.4-33.9 0L160 255.9l-96.4 96.4c-9.4 9.4-24.6 9.4-33.9 0L7 329.7c-9.4-9.4-9.4-24.6 0-33.9l136-136c9.4-9.5 24.6-9.5 34-.1z&#34;/&gt;&lt;/svg&gt;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&#34;fn:2&#34;&gt;
&lt;p&gt;&lt;a href=&#34;https://www.ithome.com.tw/news/141197&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;配備HTTPS-Only模式的Firefox 83問世 | iThome&lt;/a&gt;&amp;#160;&lt;a href=&#34;https://blog.momonga.dev/posts/hsts-vs-https-only-mode/#fnref:2&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&lt;svg xmlns=&#34;http://www.w3.org/2000/svg&#34; viewBox=&#34;0 0 320 512&#34; class=&#34;icon footnote-icon&#34;&gt;&lt;path d=&#34;M177 159.7l136 136c9.4 9.4 9.4 24.6 0 33.9l-22.6 22.6c-9.4 9.4-24.6 9.4-33.9 0L160 255.9l-96.4 96.4c-9.4 9.4-24.6 9.4-33.9 0L7 329.7c-9.4-9.4-9.4-24.6 0-33.9l136-136c9.4-9.5 24.6-9.5 34-.1z&#34;/&gt;&lt;/svg&gt;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&#34;fn:3&#34;&gt;
&lt;p&gt;&lt;a href=&#34;https://www.ithome.com.tw/news/144773&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;Microsoft Edge 92將開始預覽自動選用HTTPS功能 | iThome&lt;/a&gt;&amp;#160;&lt;a href=&#34;https://blog.momonga.dev/posts/hsts-vs-https-only-mode/#fnref:3&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&lt;svg xmlns=&#34;http://www.w3.org/2000/svg&#34; viewBox=&#34;0 0 320 512&#34; class=&#34;icon footnote-icon&#34;&gt;&lt;path d=&#34;M177 159.7l136 136c9.4 9.4 9.4 24.6 0 33.9l-22.6 22.6c-9.4 9.4-24.6 9.4-33.9 0L160 255.9l-96.4 96.4c-9.4 9.4-24.6 9.4-33.9 0L7 329.7c-9.4-9.4-9.4-24.6 0-33.9l136-136c9.4-9.5 24.6-9.5 34-.1z&#34;/&gt;&lt;/svg&gt;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&#34;fn:4&#34;&gt;
&lt;p&gt;&lt;a href=&#34;https://blog.mozilla.org/attack-and-defense/2021/03/10/insights-into-https-only-mode/&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;Insights into HTTPS-Only Mode – Attack &amp;amp; Defense&lt;/a&gt;&amp;#160;&lt;a href=&#34;https://blog.momonga.dev/posts/hsts-vs-https-only-mode/#fnref:4&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&lt;svg xmlns=&#34;http://www.w3.org/2000/svg&#34; viewBox=&#34;0 0 320 512&#34; class=&#34;icon footnote-icon&#34;&gt;&lt;path d=&#34;M177 159.7l136 136c9.4 9.4 9.4 24.6 0 33.9l-22.6 22.6c-9.4 9.4-24.6 9.4-33.9 0L160 255.9l-96.4 96.4c-9.4 9.4-24.6 9.4-33.9 0L7 329.7c-9.4-9.4-9.4-24.6 0-33.9l136-136c9.4-9.5 24.6-9.5 34-.1z&#34;/&gt;&lt;/svg&gt;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;/div&gt;

                        
                    </description>
                
                
                
                
                
                    
                        
                            
                                
                                
                                
                                    <category domain="https://blog.momonga.dev/categories/software-development/">Software Development</category>
                                
                            
                        
                    
                        
                            
                                
                                
                                
                                    <category domain="https://blog.momonga.dev/tags/browser/">Browser</category>
                                
                            
                                
                                
                                
                                    <category domain="https://blog.momonga.dev/tags/hsts/">HSTS</category>
                                
                            
                                
                                
                                
                                    <category domain="https://blog.momonga.dev/tags/cybersecurity/">Cybersecurity</category>
                                
                            
                        
                    
                
            </item>
        
            <item>
                <title>Youtube RSS Finder</title>
                <link>https://blog.momonga.dev/posts/youtube-rss-finder/</link>
                <guid isPermaLink="true">https://blog.momonga.dev/posts/youtube-rss-finder/</guid>
                <pubDate>Tue, 07 Nov 2023 16:11:53 &#43;0800</pubDate>
                
                <copyright>[CC BY-NC-SA 4.0](https://creativecommons.org/licenses/by-nc-sa/4.0/deed.en)</copyright>
                
                
                <description>
                        &lt;p&gt;YouTube 頻道是我常用的 RSS 訂閱源之一，去年十月官方全面開放「@使用者」帳號的申請&lt;sup id=&#34;fnref:1&#34;&gt;&lt;a href=&#34;https://blog.momonga.dev/posts/youtube-rss-finder/#fn:1&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;[1]&lt;/a&gt;&lt;/sup&gt;，隨著大多數人申請帳號，原本的頻道 ID (Channel ID) 就沒有出現在網址上面了。YouTube 頻道訂閱源網址的形式為 &lt;code&gt;https://www.youtube.com/feeds/videos.xml?channel_id=&amp;lt;channel_id&amp;gt;&lt;/code&gt;，channel_id 可以直接的在頻道首頁點右鍵-&amp;gt;檢視原始碼，搜尋「videos.xml」關鍵字找到，所以也不是什麼費工的事。&lt;/p&gt;
&lt;p&gt;會做 &lt;a href=&#34;https://ytrssfinder.jlhg.org&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;YouTube RSS Finder&lt;/a&gt;，最主要的動機是為了學習 Vue3 和 Rust。多年前 React 的推行，其虛擬 DOM 的概念為前端帶來變革，那時就用 React 寫了 &lt;a href=&#34;https://github.com/jlhg/bookpocket&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;bookpocket&lt;/a&gt; 的 Chrome 擴充功能。當時有在使用 &lt;a href=&#34;https://getpocket.com&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;Pocket&lt;/a&gt;，它是一種網路書籤服務，可以將網頁加進書籤管理，以便稍後閱讀或分享等。官方的擴充功能無法顯示當前網頁是否已加入書籤，如果每次都要加入的話也挺麻煩，因此利用 Pocket API 做成擴充功能，未加入的網頁，其網址列顯示藍色圖示，已加入則顯示紅色圖示。&lt;/p&gt;
&lt;p&gt;至於為什麼要學前端？只做後端雖然可以做命令列介面 (CLI) 軟體，但會操作這類介面的使用者通常都要有一點工程背景。如果有什麼想法想面向一般大眾，圖形介面 (GUI) 必不可少。想法與行動皆不受限，才有機會創造更多價值。&lt;/p&gt;
&lt;div class=&#34;footnotes&#34; role=&#34;doc-endnotes&#34;&gt;
&lt;ol&gt;
&lt;li id=&#34;fn:1&#34;&gt;
&lt;p&gt;&lt;a href=&#34;https://support.google.com/youtube/thread/183284252/%F0%9F%93%A3-announcing-youtube-handles-a-unique-identifier-to-discover-and-connect-on-youtube?hl=en&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;📣 Announcing YouTube handles: a &lt;em&gt;unique&lt;/em&gt; identifier to discover and connect on YouTube - YouTube Community&lt;/a&gt;&amp;#160;&lt;a href=&#34;https://blog.momonga.dev/posts/youtube-rss-finder/#fnref:1&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&lt;svg xmlns=&#34;http://www.w3.org/2000/svg&#34; viewBox=&#34;0 0 320 512&#34; class=&#34;icon footnote-icon&#34;&gt;&lt;path d=&#34;M177 159.7l136 136c9.4 9.4 9.4 24.6 0 33.9l-22.6 22.6c-9.4 9.4-24.6 9.4-33.9 0L160 255.9l-96.4 96.4c-9.4 9.4-24.6 9.4-33.9 0L7 329.7c-9.4-9.4-9.4-24.6 0-33.9l136-136c9.4-9.5 24.6-9.5 34-.1z&#34;/&gt;&lt;/svg&gt;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;/div&gt;

                        
                    </description>
                
                
                
                
                
                    
                        
                            
                                
                                
                                
                                    <category domain="https://blog.momonga.dev/categories/work/">Work</category>
                                
                            
                        
                    
                        
                            
                                
                                
                                
                                    <category domain="https://blog.momonga.dev/tags/youtube/">YouTube</category>
                                
                            
                                
                                
                                
                                    <category domain="https://blog.momonga.dev/tags/rss/">RSS</category>
                                
                            
                                
                                
                                
                                    <category domain="https://blog.momonga.dev/tags/extractor/">Extractor</category>
                                
                            
                        
                    
                
            </item>
        
            <item>
                <title>Firefox 119.0 中文字型無法正常顯示</title>
                <link>https://blog.momonga.dev/posts/firefox-119-font-issue/</link>
                <guid isPermaLink="true">https://blog.momonga.dev/posts/firefox-119-font-issue/</guid>
                <pubDate>Tue, 31 Oct 2023 19:32:31 &#43;0800</pubDate>
                
                <copyright>[CC BY-NC-SA 4.0](https://creativecommons.org/licenses/by-nc-sa/4.0/deed.en)</copyright>
                
                
                <description>
                        &lt;p&gt;Firefox 更新到 119.0 之後，發現原本設定的自訂中文字型（像是思源黑體）無法正常顯示在網頁上。查閱了&lt;a href=&#34;https://www.mozilla.org/en-US/firefox/119.0/releasenotes/&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;更新日誌&lt;/a&gt;，有一段寫著：&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;The visibility of fonts to websites has been restricted to system fonts and language pack fonts in Enhanced Tracking Protection strict mode to mitigate font fingerprinting.&lt;/p&gt;&lt;/blockquote&gt;
&lt;p&gt;Firefox 119.0 加入了字型指紋 (font fingerprinting)&lt;sup id=&#34;fnref:1&#34;&gt;&lt;a href=&#34;https://blog.momonga.dev/posts/firefox-119-font-issue/#fn:1&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;[1]&lt;/a&gt;&lt;/sup&gt; 保護機制，在加強型追蹤保護的嚴格模式下，只允許渲染作業系統內建及語言包的字型。&lt;/p&gt;
&lt;p&gt;要解決這個問題，可以改成自訂模式，將「疑似是數位指紋追蹤程式」限定於隱私瀏覽視窗或取消選取&lt;sup id=&#34;fnref:2&#34;&gt;&lt;a href=&#34;https://blog.momonga.dev/posts/firefox-119-font-issue/#fn:2&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;[2]&lt;/a&gt;&lt;/sup&gt;。&lt;/p&gt;
&lt;div class=&#34;footnotes&#34; role=&#34;doc-endnotes&#34;&gt;
&lt;ol&gt;
&lt;li id=&#34;fn:1&#34;&gt;
&lt;p&gt;&lt;a href=&#34;https://web-tracking.allenchou.cc/docs/browser-fingerprinting/techniques/fonts-enumeration/&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;Fonts Fingerprinting | Web Tracking 筆記&lt;/a&gt;&amp;#160;&lt;a href=&#34;https://blog.momonga.dev/posts/firefox-119-font-issue/#fnref:1&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&lt;svg xmlns=&#34;http://www.w3.org/2000/svg&#34; viewBox=&#34;0 0 320 512&#34; class=&#34;icon footnote-icon&#34;&gt;&lt;path d=&#34;M177 159.7l136 136c9.4 9.4 9.4 24.6 0 33.9l-22.6 22.6c-9.4 9.4-24.6 9.4-33.9 0L160 255.9l-96.4 96.4c-9.4 9.4-24.6 9.4-33.9 0L7 329.7c-9.4-9.4-9.4-24.6 0-33.9l136-136c9.4-9.5 24.6-9.5 34-.1z&#34;/&gt;&lt;/svg&gt;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&#34;fn:2&#34;&gt;
&lt;p&gt;&lt;a href=&#34;https://support.mozilla.org/nl/questions/1428532#answer-1613377&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;Default fonts not showing correctly | Firefox-ondersteuningsforum | Mozilla Support&lt;/a&gt;&amp;#160;&lt;a href=&#34;https://blog.momonga.dev/posts/firefox-119-font-issue/#fnref:2&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&lt;svg xmlns=&#34;http://www.w3.org/2000/svg&#34; viewBox=&#34;0 0 320 512&#34; class=&#34;icon footnote-icon&#34;&gt;&lt;path d=&#34;M177 159.7l136 136c9.4 9.4 9.4 24.6 0 33.9l-22.6 22.6c-9.4 9.4-24.6 9.4-33.9 0L160 255.9l-96.4 96.4c-9.4 9.4-24.6 9.4-33.9 0L7 329.7c-9.4-9.4-9.4-24.6 0-33.9l136-136c9.4-9.5 24.6-9.5 34-.1z&#34;/&gt;&lt;/svg&gt;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;/div&gt;

                        
                    </description>
                
                
                
                
                
                    
                        
                            
                                
                                
                                
                                    <category domain="https://blog.momonga.dev/categories/config/">Config</category>
                                
                            
                        
                    
                        
                            
                                
                                
                                
                                    <category domain="https://blog.momonga.dev/tags/firefox/">Firefox</category>
                                
                            
                                
                                
                                
                                    <category domain="https://blog.momonga.dev/tags/font-fingerprinting/">Font Fingerprinting</category>
                                
                            
                                
                                
                                
                                    <category domain="https://blog.momonga.dev/tags/cybersecurity/">Cybersecurity</category>
                                
                            
                        
                    
                
            </item>
        
            <item>
                <title>我的待辦工具遷移史</title>
                <link>https://blog.momonga.dev/posts/my-todo-app-migration/</link>
                <guid isPermaLink="true">https://blog.momonga.dev/posts/my-todo-app-migration/</guid>
                <pubDate>Mon, 16 Oct 2023 18:58:47 &#43;0800</pubDate>
                
                <copyright>[CC BY-NC-SA 4.0](https://creativecommons.org/licenses/by-nc-sa/4.0/deed.en)</copyright>
                
                
                <description>
                        &lt;p&gt;Wunderlsit (奇妙清單) 待辦工具於 2015 年被微軟收購（後被關閉），四年後創辦人 Christian Reber 反悔，表示想把產品買回來&lt;sup id=&#34;fnref:1&#34;&gt;&lt;a href=&#34;https://blog.momonga.dev/posts/my-todo-app-migration/#fn:1&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;[1]&lt;/a&gt;&lt;/sup&gt;，豈料未果。他於 2020 年另起爐灶，創立了競品 Superlist&lt;sup id=&#34;fnref:2&#34;&gt;&lt;a href=&#34;https://blog.momonga.dev/posts/my-todo-app-migration/#fn:2&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;[2]&lt;/a&gt;&lt;/sup&gt;，如今已漸成熟，我在上週三收到了 Private Beta 測試邀請。&lt;/p&gt;
&lt;p&gt;我的待辦工具軟體，最早是用 Emacs &lt;a href=&#34;https://orgmode.org/&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;Org Mode&lt;/a&gt; 搭配 Google Drive 同步功能，當智慧型手機慢慢流行以後，對於沒有好用的行動版應用程式相當不太方便，尤其是通知功能；加上 Windows 也要安裝 Emacs，Org Mode 對跨平台實在不太友善。&lt;/p&gt;
&lt;p&gt;後來改用 Google Tasks，這款應用綁在 Gmail 介面下，在側邊欄就可以操作，相當方便。漸漸我不再以 Gmail 作為主要 Email 產品，Google Tasks 也沒有獨立的 Web 介面&lt;sup id=&#34;fnref:3&#34;&gt;&lt;a href=&#34;https://blog.momonga.dev/posts/my-todo-app-migration/#fn:3&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;[3]&lt;/a&gt;&lt;/sup&gt;，於是再尋找其他的替代品。&lt;/p&gt;
&lt;p&gt;思考良久，一款符合我期待的待辦工具應用，必須符合以下條件：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;跨平台 (Windows / macOS / iOS)&lt;/li&gt;
&lt;li&gt;To-Do 功能導向，非筆記&lt;/li&gt;
&lt;li&gt;尊重隱私，最好符合 &lt;a href=&#34;https://zh.wikipedia.org/zh-tw/%E6%AD%90%E7%9B%9F%E4%B8%80%E8%88%AC%E8%B3%87%E6%96%99%E4%BF%9D%E8%AD%B7%E8%A6%8F%E7%AF%84&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;GDPR&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;不 Lag 的使用操作體驗&lt;/li&gt;
&lt;li&gt;支援資料匯出（可以離線儲存更好）&lt;/li&gt;
&lt;li&gt;支援上傳附件&lt;/li&gt;
&lt;li&gt;多時段通知功能&lt;/li&gt;
&lt;li&gt;重複建立功能（當任務勾選完成後，自動建立重複任務）&lt;/li&gt;
&lt;li&gt;支援 &lt;a href=&#34;https://developer.apple.com/documentation/foundation/app_extension_support/supporting_suggestions_in_your_app_s_share_extension&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;Share Extension&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;支援 &lt;a href=&#34;https://zh.wikipedia.org/zh-tw/ICalendar&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;iCalendar&lt;/a&gt;（方便整合到行事曆）&lt;/li&gt;
&lt;li&gt;良好的客服信譽&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Self-Hosted Open Source 是我的首選，然而調查了一輪，沒有找到我滿意的應用程式。&lt;/p&gt;
&lt;p&gt;接著找到 &lt;a href=&#34;https://todoist.com&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;Todoist&lt;/a&gt;，覺得滿意，也使用了好幾年。某天我發現一個清單包含 300 個以上（未完成）任務時，會極度 Lag（早期我還把它當作網頁 read later 在用），影響使用體驗。Wunderlist 是跟 Todoist 介面最為相近的軟體，轉到 Wunderlist 沒多久就傳來被微軟收購的消息，心得不多。&lt;/p&gt;
&lt;p&gt;最後使用 &lt;a href=&#34;https://ticktick.com&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;TickTick&lt;/a&gt;。TickTick 後來出了一個我不太喜歡的功能，該功能會自動的將標題內的網址轉換為 Markdown 格式的網站標題及連結，問題在於有些網址需要登入權限或有阻擋爬蟲，標題會變成「系統異常回報」或「需登入」之類的文字，無法根據標題判斷為不同的待辦事項。該功能也不能 opt-out。寫信建議客服也僅得到了我們會考慮的回覆。&lt;/p&gt;
&lt;p&gt;TickTick 不是我的終點，Superlist 仍在觀望，期待未來可以脫胎換骨。&lt;/p&gt;
&lt;div class=&#34;footnotes&#34; role=&#34;doc-endnotes&#34;&gt;
&lt;ol&gt;
&lt;li id=&#34;fn:1&#34;&gt;
&lt;p&gt;&lt;a href=&#34;https://technews.tw/2019/09/10/christian-reber-wants-to-buy-wunderlist/&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;被微軟收購 4 年後，「Wunderlist」的創始人想把產品買回來 | TechNews 科技新報&lt;/a&gt;&amp;#160;&lt;a href=&#34;https://blog.momonga.dev/posts/my-todo-app-migration/#fnref:1&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&lt;svg xmlns=&#34;http://www.w3.org/2000/svg&#34; viewBox=&#34;0 0 320 512&#34; class=&#34;icon footnote-icon&#34;&gt;&lt;path d=&#34;M177 159.7l136 136c9.4 9.4 9.4 24.6 0 33.9l-22.6 22.6c-9.4 9.4-24.6 9.4-33.9 0L160 255.9l-96.4 96.4c-9.4 9.4-24.6 9.4-33.9 0L7 329.7c-9.4-9.4-9.4-24.6 0-33.9l136-136c9.4-9.5 24.6-9.5 34-.1z&#34;/&gt;&lt;/svg&gt;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&#34;fn:2&#34;&gt;
&lt;p&gt;&lt;a href=&#34;https://technews.tw/2020/05/07/as-wunderlist-shuts-down-its-founder-announces-a-new-productivity-app-called-superlist/&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;Wunderlist 創辦人另起爐灶，公布新產品 Superlist | TechNews 科技新報&lt;/a&gt;&amp;#160;&lt;a href=&#34;https://blog.momonga.dev/posts/my-todo-app-migration/#fnref:2&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&lt;svg xmlns=&#34;http://www.w3.org/2000/svg&#34; viewBox=&#34;0 0 320 512&#34; class=&#34;icon footnote-icon&#34;&gt;&lt;path d=&#34;M177 159.7l136 136c9.4 9.4 9.4 24.6 0 33.9l-22.6 22.6c-9.4 9.4-24.6 9.4-33.9 0L160 255.9l-96.4 96.4c-9.4 9.4-24.6 9.4-33.9 0L7 329.7c-9.4-9.4-9.4-24.6 0-33.9l136-136c9.4-9.5 24.6-9.5 34-.1z&#34;/&gt;&lt;/svg&gt;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&#34;fn:3&#34;&gt;
&lt;p&gt;&lt;a href=&#34;https://www.reddit.com/r/Android/comments/anh8yu/all_roads_lead_to_gmail_google_is_shutting_down/&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;All roads lead to Gmail: Google is shutting down the classic Tasks web UI : r/Android&lt;/a&gt;&amp;#160;&lt;a href=&#34;https://blog.momonga.dev/posts/my-todo-app-migration/#fnref:3&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&lt;svg xmlns=&#34;http://www.w3.org/2000/svg&#34; viewBox=&#34;0 0 320 512&#34; class=&#34;icon footnote-icon&#34;&gt;&lt;path d=&#34;M177 159.7l136 136c9.4 9.4 9.4 24.6 0 33.9l-22.6 22.6c-9.4 9.4-24.6 9.4-33.9 0L160 255.9l-96.4 96.4c-9.4 9.4-24.6 9.4-33.9 0L7 329.7c-9.4-9.4-9.4-24.6 0-33.9l136-136c9.4-9.5 24.6-9.5 34-.1z&#34;/&gt;&lt;/svg&gt;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;/div&gt;

                        
                    </description>
                
                
                
                
                
                    
                        
                            
                                
                                
                                
                                    <category domain="https://blog.momonga.dev/categories/software/">Software</category>
                                
                            
                        
                    
                        
                            
                                
                                
                                
                                    <category domain="https://blog.momonga.dev/tags/superlist/">Superlist</category>
                                
                            
                                
                                
                                
                                    <category domain="https://blog.momonga.dev/tags/wunderlist/">Wunderlist</category>
                                
                            
                                
                                
                                
                                    <category domain="https://blog.momonga.dev/tags/todoist/">Todoist</category>
                                
                            
                                
                                
                                
                                    <category domain="https://blog.momonga.dev/tags/ticktick/">TickTick</category>
                                
                            
                                
                                
                                
                                    <category domain="https://blog.momonga.dev/tags/to-do-list/">To-Do List</category>
                                
                            
                                
                                
                                
                                    <category domain="https://blog.momonga.dev/tags/%E5%BE%85%E8%BE%A6%E5%B7%A5%E5%85%B7/">待辦工具</category>
                                
                            
                                
                                
                                
                                    <category domain="https://blog.momonga.dev/tags/%E7%94%9F%E7%94%A2%E5%8A%9B%E5%B7%A5%E5%85%B7/">生產力工具</category>
                                
                            
                                
                                
                                
                                    <category domain="https://blog.momonga.dev/tags/review/">Review</category>
                                
                            
                        
                    
                
            </item>
        
            <item>
                <title>修復 Windows 檔案總管預覽 PDF 出錯</title>
                <link>https://blog.momonga.dev/posts/fix-pdf-preview-on-windows-explorer/</link>
                <guid isPermaLink="true">https://blog.momonga.dev/posts/fix-pdf-preview-on-windows-explorer/</guid>
                <pubDate>Mon, 12 Sep 2022 18:38:23 &#43;0800</pubDate>
                
                <copyright>[CC BY-NC-SA 4.0](https://creativecommons.org/licenses/by-nc-sa/4.0/deed.en)</copyright>
                
                
                <description>
                        &lt;p&gt;今天 Adobe Acrobat Reader 在檔案總管預覽 PDF 時出現了不明的錯誤。&lt;br&gt;
&lt;img src=&#34;https://blog.momonga.dev/img/fix-pdf-preview-on-windows-explorer/acrobat-internal-error.png&#34; alt=&#34;&#34;&gt;&lt;/p&gt;
&lt;p&gt;因為想要測試 Adobe 軟體能不能在 &lt;a href=&#34;https://sandboxie-plus.com/&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;Sandboxie&lt;/a&gt; 沙盒內正常運作，故解除安裝原本裝好的 Adobe Creative Cloud，也連帶解除安裝 Acrobat Reader DC。當測試完 (並且失敗) 裝回 Acrobat Reader，發現在檔案總管點選 PDF 檔案，游標持續呈現沙漏（卡頓）。十數秒後，出現上圖的錯誤，猜測是預覽窗格造成的問題。&lt;/p&gt;
&lt;p&gt;嘗試過用 &lt;a href=&#34;https://helpx.adobe.com/tw/creative-cloud/kb/cc-cleaner-tool-installation-problems.html&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;Creative Cloud Cleaner Tool&lt;/a&gt;&lt;sup id=&#34;fnref:1&#34;&gt;&lt;a href=&#34;https://blog.momonga.dev/posts/fix-pdf-preview-on-windows-explorer/#fn:1&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;[1]&lt;/a&gt;&lt;/sup&gt; 和 &lt;a href=&#34;https://www.adobe.com/devnet-docs/acrobatetk/tools/Labs/cleaner.html&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;AcroCleaner&lt;/a&gt;&lt;sup id=&#34;fnref:2&#34;&gt;&lt;a href=&#34;https://blog.momonga.dev/posts/fix-pdf-preview-on-windows-explorer/#fn:2&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;[2]&lt;/a&gt;&lt;/sup&gt;，希望能將 Adobe 軟體徹底從系統清除，再重安裝，看看有沒有修復。&lt;/p&gt;
&lt;p&gt;結果失敗了。&lt;/p&gt;
&lt;p&gt;Acrobat Reader 的偏好設定裡面，「啟用 Windows 檔案總管中的 PDF 縮圖預覽」選取後會安裝新的模組，這項功能就算啟用，依然會出現錯誤。&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;https://blog.momonga.dev/img/fix-pdf-preview-on-windows-explorer/acrobat-enable-pdf-preview.png&#34; alt=&#34;&#34;&gt;&lt;/p&gt;
&lt;p&gt;後來我看到&lt;a href=&#34;https://www.thewindowsclub.com/preview-for-pdf-not-displaying-correctly-shows-index-of-in-explorer&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;這一篇文章&lt;/a&gt;，提到可以透過修改機碼來改變檔案總管的 PreviewHandler。最終我將 PDF PreviewHandler 換成微軟自家的，算是解決了這個問題，而且預覽窗格渲染的速度也變得相當快。&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;從 &lt;code&gt;\HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\PreviewHandlers&lt;/code&gt; 可以看到機碼為 &lt;code&gt;{DC6EFB56-9CFA-464D-8880-44885D7DC193}&lt;/code&gt; 的是 Acrobat Reader 的預覽處理常式。&lt;br&gt;
&lt;img src=&#34;https://blog.momonga.dev/img/fix-pdf-preview-on-windows-explorer/reg-acrobat.png&#34; alt=&#34;&#34;&gt;&lt;/p&gt;
&lt;p&gt;而 &lt;code&gt;{3A84F9C2-6164-485C-A7D9-4B27F8AC009E}&lt;/code&gt; 則是 Microsoft PDF Previewer。&lt;br&gt;
&lt;img src=&#34;https://blog.momonga.dev/img/fix-pdf-preview-on-windows-explorer/reg-ms.png&#34; alt=&#34;&#34;&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;到 &lt;code&gt;\HKEY_CLASSES_ROOT\.pdf\ShellEx\{8895b1c6-b41f-4c1c-a562-0d564250836f}&lt;/code&gt; 底下打開名為 &lt;code&gt;(預設值)&lt;/code&gt; 的機碼，將數值改成 &lt;code&gt;{3A84F9C2-6164-485C-A7D9-4B27F8AC009E}&lt;/code&gt;，就完成了。&lt;br&gt;
&lt;img src=&#34;https://blog.momonga.dev/img/fix-pdf-preview-on-windows-explorer/reg-pdf.png&#34; alt=&#34;&#34;&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;div class=&#34;footnotes&#34; role=&#34;doc-endnotes&#34;&gt;
&lt;ol&gt;
&lt;li id=&#34;fn:1&#34;&gt;
&lt;p&gt;&lt;a href=&#34;https://adobe.fandom.com/wiki/Adobe_Creative_Cloud_Cleaner_Tool&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;Adobe Creative Cloud Cleaner Tool | Adobe Wiki | Fandom&lt;/a&gt;&amp;#160;&lt;a href=&#34;https://blog.momonga.dev/posts/fix-pdf-preview-on-windows-explorer/#fnref:1&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&lt;svg xmlns=&#34;http://www.w3.org/2000/svg&#34; viewBox=&#34;0 0 320 512&#34; class=&#34;icon footnote-icon&#34;&gt;&lt;path d=&#34;M177 159.7l136 136c9.4 9.4 9.4 24.6 0 33.9l-22.6 22.6c-9.4 9.4-24.6 9.4-33.9 0L160 255.9l-96.4 96.4c-9.4 9.4-24.6 9.4-33.9 0L7 329.7c-9.4-9.4-9.4-24.6 0-33.9l136-136c9.4-9.5 24.6-9.5 34-.1z&#34;/&gt;&lt;/svg&gt;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&#34;fn:2&#34;&gt;
&lt;p&gt;&lt;a href=&#34;https://adobe.fandom.com/wiki/Adobe_Acrobat_Cleaner_Tool&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;Adobe Acrobat Cleaner Tool | Adobe Wiki | Fandom&lt;/a&gt;&amp;#160;&lt;a href=&#34;https://blog.momonga.dev/posts/fix-pdf-preview-on-windows-explorer/#fnref:2&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&lt;svg xmlns=&#34;http://www.w3.org/2000/svg&#34; viewBox=&#34;0 0 320 512&#34; class=&#34;icon footnote-icon&#34;&gt;&lt;path d=&#34;M177 159.7l136 136c9.4 9.4 9.4 24.6 0 33.9l-22.6 22.6c-9.4 9.4-24.6 9.4-33.9 0L160 255.9l-96.4 96.4c-9.4 9.4-24.6 9.4-33.9 0L7 329.7c-9.4-9.4-9.4-24.6 0-33.9l136-136c9.4-9.5 24.6-9.5 34-.1z&#34;/&gt;&lt;/svg&gt;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;/div&gt;

                        
                    </description>
                
                
                
                
                
                    
                        
                            
                                
                                
                                
                                    <category domain="https://blog.momonga.dev/categories/config/">Config</category>
                                
                            
                        
                    
                        
                            
                                
                                
                                
                                    <category domain="https://blog.momonga.dev/tags/windows/">Windows</category>
                                
                            
                                
                                
                                
                                    <category domain="https://blog.momonga.dev/tags/windows-11/">Windows 11</category>
                                
                            
                                
                                
                                
                                    <category domain="https://blog.momonga.dev/tags/adobe-acrobat-reader/">Adobe Acrobat Reader</category>
                                
                            
                                
                                
                                
                                    <category domain="https://blog.momonga.dev/tags/pdf/">PDF</category>
                                
                            
                        
                    
                
            </item>
        
            <item>
                <title>在路由器安裝 OpenWrt 及 WireGuard VPN</title>
                <link>https://blog.momonga.dev/posts/install-wireguard-vpn-on-openwrt/</link>
                <guid isPermaLink="true">https://blog.momonga.dev/posts/install-wireguard-vpn-on-openwrt/</guid>
                <pubDate>Mon, 12 Sep 2022 00:13:54 &#43;0800</pubDate>
                
                <copyright>[CC BY-NC-SA 4.0](https://creativecommons.org/licenses/by-nc-sa/4.0/deed.en)</copyright>
                
                
                <description>
                        &lt;p&gt;最近買了一台空氣清淨機，附有 Wifi 功能，可以隨時透過 App 偵測室內空氣品質。我覺得這點做得滿棒的，但因為數據是直接傳到廠商的伺服器，想把對外的 IP 隱藏起來，興起了想透過路由器設定 VPN 的念頭。&lt;/p&gt;
&lt;p&gt;原本相中 &lt;a href=&#34;https://shop.pcwrt.com/&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;PCWRT&lt;/a&gt; 家的路由器，但正逢缺貨，作為替代找了一款便宜的迷你型路由器 GL.iNet GL-MT300N，用的是聯發科晶片，可以安裝 OpenWrt 系統。&lt;/p&gt;
&lt;p&gt;以下簡要敘述安裝的過程。&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;到 &lt;a href=&#34;https://openwrt.org/toh/gl.inet/gl-mt300n_v2#installation&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;OpenWrt 官網&lt;/a&gt; 下載預先編譯好的韌體。&lt;br&gt;
&lt;img src=&#34;https://blog.momonga.dev/img/install-wireguard-vpn-on-openwrt/openwrt-installation.png&#34; alt=&#34;&#34;&gt;&lt;/li&gt;
&lt;li&gt;將路由器接上電源、連上 Wifi 後，進入 &lt;code&gt;http://192.168.8.1&lt;/code&gt;，上傳並安裝 OpenWrt 韌體檔。&lt;/li&gt;
&lt;li&gt;安裝後，透過 LAN 連線，確定連線並取得 DHCP IP，進入 &lt;code&gt;http://192.168.1.1&lt;/code&gt;，預設帳號及密碼皆為 root。&lt;br&gt;
&lt;img src=&#34;https://blog.momonga.dev/img/install-wireguard-vpn-on-openwrt/lan-connection.png&#34; alt=&#34;&#34;&gt;&lt;/li&gt;
&lt;li&gt;到 System ➔ Software，點擊 &lt;code&gt;Update lists...&lt;/code&gt; 按鈕，等待系統更新 package 列表。Filter 搜尋 &lt;code&gt;wireguard&lt;/code&gt;，找到 &lt;code&gt;luci-app-wireguard&lt;/code&gt; 並安裝。安裝完到 System ➔ Reboot 重啟系統。&lt;br&gt;
&lt;img src=&#34;https://blog.momonga.dev/img/install-wireguard-vpn-on-openwrt/install-luci-app-wireguard.png&#34; alt=&#34;&#34;&gt;&lt;/li&gt;
&lt;li&gt;到 Network ➔ Interfaces 新增 WireGuard 介面，名稱隨意訂，Protocol 選 &lt;code&gt;WireGuard VPN&lt;/code&gt;，點建立。&lt;br&gt;
&lt;img src=&#34;https://blog.momonga.dev/img/install-wireguard-vpn-on-openwrt/create-wg-interface.png&#34; alt=&#34;&#34;&gt;&lt;/li&gt;
&lt;li&gt;編輯 WireGuard 介面，透過最下方的 Import configuration 匯入 從 ProtonVPN 網站生成的 WireGuard config 檔。&lt;/li&gt;
&lt;li&gt;編輯 WAN 介面，切換到 Advanced Settings 分頁，取消勾選 Use DNS servers advertised by peer，然後在 Use custom DNS servers 填入 ProtonVPN config 檔所提供的 DNS server 位址。&lt;br&gt;
&lt;img src=&#34;https://blog.momonga.dev/img/install-wireguard-vpn-on-openwrt/edit-wan-dns.png&#34; alt=&#34;&#34;&gt;&lt;br&gt;
&lt;img src=&#34;https://blog.momonga.dev/img/install-wireguard-vpn-on-openwrt/edit-wan-dns-2.png&#34; alt=&#34;&#34;&gt;&lt;/li&gt;
&lt;li&gt;到 Network ➔ Firewall 新增 Zone，名稱隨意取，Input 選 &lt;code&gt;rejected&lt;/code&gt;、Output 選 &lt;code&gt;accepted&lt;/code&gt;、Forward 選 &lt;code&gt;rejected&lt;/code&gt;，Masquerading 和 MSS clamping 都勾選；Covered networks 選剛剛建立的 WireGuard 介面；Allow forward from source zones 選 lan 介面。&lt;br&gt;
&lt;img src=&#34;https://blog.momonga.dev/img/install-wireguard-vpn-on-openwrt/create-firewall-zone.png&#34; alt=&#34;&#34;&gt;&lt;/li&gt;
&lt;li&gt;如果想要在 VPN 連不上的時候斷開網路，不要改連 WAN，就要設定 Kill Switch。編輯 lan zone，從 Allow forward to destination zones 移除 WAN 介面，只留下 WireGuard 介面。&lt;br&gt;
&lt;img src=&#34;https://blog.momonga.dev/img/install-wireguard-vpn-on-openwrt/kill-switch.png&#34; alt=&#34;&#34;&gt;&lt;/li&gt;
&lt;li&gt;至此就設定完成了。可以在連線 LAN 後檢查 WireGuard 介面的 RX 跟 TX 有沒有收到封包，若有代表有成功透過 WireGuard 介面傳輸。&lt;br&gt;
&lt;img src=&#34;https://blog.momonga.dev/img/install-wireguard-vpn-on-openwrt/wg0-test.png&#34; alt=&#34;&#34;&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;h1 id=&#34;參考資料&#34;&gt;&lt;a href=&#34;https://blog.momonga.dev/posts/install-wireguard-vpn-on-openwrt/#參考資料&#34; class=&#34;anchor-link&#34;&gt;&lt;svg xmlns=&#34;http://www.w3.org/2000/svg&#34; viewBox=&#34;0 0 512 512&#34; class=&#34;icon anchor-icon&#34;&gt;&lt;path d=&#34;M326.612 185.391c59.747 59.809 58.927 155.698.36 214.59-.11.12-.24.25-.36.37l-67.2 67.2c-59.27 59.27-155.699 59.262-214.96 0-59.27-59.26-59.27-155.7 0-214.96l37.106-37.106c9.84-9.84 26.786-3.3 27.294 10.606.648 17.722 3.826 35.527 9.69 52.721 1.986 5.822.567 12.262-3.783 16.612l-13.087 13.087c-28.026 28.026-28.905 73.66-1.155 101.96 28.024 28.579 74.086 28.749 102.325.51l67.2-67.19c28.191-28.191 28.073-73.757 0-101.83-3.701-3.694-7.429-6.564-10.341-8.569a16.037 16.037 0 0 1-6.947-12.606c-.396-10.567 3.348-21.456 11.698-29.806l21.054-21.055c5.521-5.521 14.182-6.199 20.584-1.731a152.482 152.482 0 0 1 20.522 17.197zM467.547 44.449c-59.261-59.262-155.69-59.27-214.96 0l-67.2 67.2c-.12.12-.25.25-.36.37-58.566 58.892-59.387 154.781.36 214.59a152.454 152.454 0 0 0 20.521 17.196c6.402 4.468 15.064 3.789 20.584-1.731l21.054-21.055c8.35-8.35 12.094-19.239 11.698-29.806a16.037 16.037 0 0 0-6.947-12.606c-2.912-2.005-6.64-4.875-10.341-8.569-28.073-28.073-28.191-73.639 0-101.83l67.2-67.19c28.239-28.239 74.3-28.069 102.325.51 27.75 28.3 26.872 73.934-1.155 101.96l-13.087 13.087c-4.35 4.35-5.769 10.79-3.783 16.612 5.864 17.194 9.042 34.999 9.69 52.721.509 13.906 17.454 20.446 27.294 10.606l37.106-37.106c59.271-59.259 59.271-155.699.001-214.959z&#34;/&gt;&lt;/svg&gt;&lt;/a&gt;參考資料&lt;/h1&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&#34;https://www.vpnunlimited.com/help/manuals/open-wrt-wireguard-setup&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;WireGuard® VPN Client Setup for OpenWrt router - VPN Unlimited&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://www.youtube.com/watch?v=04q41GEPvKA&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;How To Set Up A VPN On A Router // Wireguard on OpenWrt - YouTube&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

                        
                    </description>
                
                
                
                
                
                    
                        
                            
                                
                                
                                
                                    <category domain="https://blog.momonga.dev/categories/config/">Config</category>
                                
                            
                        
                    
                        
                            
                                
                                
                                
                                    <category domain="https://blog.momonga.dev/tags/wireguard/">WireGuard</category>
                                
                            
                                
                                
                                
                                    <category domain="https://blog.momonga.dev/tags/openwrt/">OpenWrt</category>
                                
                            
                                
                                
                                
                                    <category domain="https://blog.momonga.dev/tags/protonvpn/">ProtonVPN</category>
                                
                            
                                
                                
                                
                                    <category domain="https://blog.momonga.dev/tags/vpn/">VPN</category>
                                
                            
                                
                                
                                
                                    <category domain="https://blog.momonga.dev/tags/%E8%B7%AF%E7%94%B1%E5%99%A8/">路由器</category>
                                
                            
                        
                    
                
            </item>
        
    </channel>
</rss>
