SheepDev

資料格式與結構化資料

YAML 設定無法載入,如何檢查語法?

使用工具

複製設定並加幾行後,某個服務的設定不生效。把 Tab 改成空白後錯誤消失,行為卻仍不對。YAML 的問題不只是語法無效,也可能是合法文字描述了與你想像不同的階層。

這裡使用虛構的 server 與 worker,不將設定套用到實際服務。用 YAML 格式化與驗證檢查語法,需要時透過 JSON 與 YAML 轉換觀察結構與型別。目標是能說明欄位屬於哪個上層,而不是格式化成功後就覆蓋正式設定。

修改前,先縮小問題範圍

數百行設定報錯時,先自行保留工作副本,再擷取相關上層與子項。只複製子項可能改變縮排上下文,導致無法重現。保留上層行、在編輯器中顯示空白、區分 Tab 與空白,比全域取代更容易確認原因與修復的關係。

兩個空白,可能改變設定的歸屬

例 A:timeout 屬於 server
server:
  host: example.invalid
  timeout: 30
worker:
  enabled: true
例 B:timeout 位於根階層
server:
  host: example.invalid
timeout: 30
worker:
  enabled: true

將兩個範例分別放進 YAML 格式化與驗證。兩者都能剖析,但結構不同:A 把 timeout 放在 server 內,B 則與 server 同級。檢查無錯誤後,還要看 timeout 屬於哪個上層。行首空白不是裝飾。

如果不易看清,可以將兩份範例轉成 JSON,觀察大括號範圍。A 是 server.timeout,B 是根階層 timeout。轉換只是觀察關係的輔助,不代表必須移轉成 JSON。正確位置仍需對照接收服務的設定規範。

加上連字號,可能就成了另一筆

兩個服務的清單
services:
  - name: api
    port: 8080
  - name: worker
    port: 8081

這裡有兩個連字號,對應兩個清單元素。每個 port 與前面的 name 同屬一筆。如果在 port 前也加連字號,可能變成只含連接埠的獨立元素,形成外觀相似的四筆清單。要同時核對數量,以及名稱與連接埠是否配對。

格式化工具不知道你想要兩筆還是四筆,只會整理能讀到的結構。將設定移到另一層時,應先確定其全部子項,而不是只移動一行。比較前後結果前,先記下預期元素數量,有助於發現意外分組。

false 與 "false" 不只是外觀不同

比較型別的小範例
enabled: false
label: "false"
count: 3
code: "003"
note: null
empty: ""

轉成 JSON 後,enabled 是布林值,label 是字串,count 是數字,code 是保留前導零的字串。note 為 null,empty 為空字串。顯示相似不代表程式同樣處理,編號若先依數字讀取而遺失前導零,之後格式化也無法可靠還原。

也不能因此把所有值都加引號,true 或 30 變成字串後可能不符合接收端要求。引號用於表達字串意圖,不是隱藏錯誤。YAML 版本與讀取方式可能不同,其他工具能剖析,不能取代實際接收端的驗證。

同一個鍵寫兩次,後面的會覆蓋嗎?

會被拒絕的重複鍵
timeout: 30
timeout: 60

SheepDev 會將此例視為重複鍵而拒絕。應先確定要保留哪個值,而不是預設後者優先。疊加多個設定檔與在同一映射中重複鍵不同,不能將框架的檔案合併規則直接套用到文件內部重複。

但 server.timeout 與 worker.timeout 上層不同,是兩個設定。全文搜尋找到兩次 timeout,不代表應該刪除其中一次。修復重複前也要先看階層,一般重複行移除工具不懂設定結構,可能刪掉必要欄位。

兩行文字為什麼會變成一行

兩種多行字串
literal: |
  first line
  second line
folded: >
  first line
  second line

轉成 JSON 後,literal 保留中間換行,folded 則用空白連接這兩行。本例兩者結尾都有換行。寫法都是兩行,不代表讀出的字串相同;通知文字、簽章內容與傳給指令的文字都可能受影響。

這個實驗只涉及相同縮排的普通兩行,不要推論包含空行或額外縮排的文字也會被 > 全部合成一行。應擷取實際使用的代表片段,檢查轉換後的換行。除了原始檔是否美觀,還要確認讀取後的文字符合預期。

複製時,也要檢查註解與值的界線

區分值內符號與註解
color: "#4F46E5"
message: "status: ready"
retries: 3 # calculation example

顏色中的 # 或句子中的冒號需要當作內容時,可以用引號明確表示字串。retries 後的註解不屬於數字 3。複製文章範例時,也應分清輸入與說明,不要因符號看起來可疑就刪除,否則可能破壞顏色或文字。

轉成 JSON 後,註解不會當作一般資料保留。YAML 格式化與跨格式轉換保留的資訊不同。如果註解說明了維運決策,不應只用轉換結果取代原檔。區分觀察用副本與團隊維護的正式設定,可避免混淆。

從能剖析,走向符合意圖

最後檢查應用要求的欄位名稱、型別與必填項。YAML 語法無法決定 timeout 是秒還是毫秒,也無法決定服務允許哪些連接埠。SheepDev 不會將設定傳送或套用到服務,也不執行其專用啟動驗證。如有設定檢查指令或安全測試環境,應繼續在那裡確認。

說明修復時,只說「改了縮排」可能不夠。說「把 timeout 從根階層移回 server 下,保留數值 30」,就能說明結構與值分別檢查過。依序確認能否剖析、階層是否符合意圖、意義是否符合應用,可避免一直追著空白修改。

參考資料

使用工具

指南 →