Jelajahi Sumber

fix: handle empty DNSPod record lists

AI-Co-Authored-By: Codex
chendeben 1 bulan lalu
induk
melakukan
0148f72b55
2 mengubah file dengan 37 tambahan dan 0 penghapusan
  1. 10 0
      src/dns-providers.js
  2. 27 0
      test/dns-providers.test.js

+ 10 - 0
src/dns-providers.js

@@ -363,6 +363,9 @@ class DnspodProvider {
     if (!response.ok || data.Response?.Error) {
       const error = new Error(data.Response?.Error?.Message || `Tencent Cloud HTTP ${response.status}`);
       error.code = data.Response?.Error?.Code || '';
+      if (action === 'DescribeRecordList' && isDnsPodEmptyRecordListError(error)) {
+        return { RecordList: [] };
+      }
       throw error;
     }
     return data.Response;
@@ -445,6 +448,13 @@ function isDnsPodZoneMissingError(error) {
     || /domain not found|domain does not exist|域名.*(不存在|没有)|没有.*域名/i.test(message);
 }
 
+function isDnsPodEmptyRecordListError(error) {
+  const code = String(error?.code || '');
+  const message = String(error?.message || '');
+  return /RecordListEmpty/i.test(code)
+    || /记录列表为空|record list.*empty|empty record list/i.test(message);
+}
+
 function isAliyunZoneMissingError(error) {
   const code = String(error?.code || '');
   const message = String(error?.message || '');

+ 27 - 0
test/dns-providers.test.js

@@ -133,6 +133,33 @@ test('dnspod provider signs and sends create record actions', async () => {
   assert.ok(actions.includes('CreateRecord'));
 });
 
+test('dnspod provider treats empty record list responses as no existing records', async () => {
+  const actions = [];
+  globalThis.fetch = async (url, options = {}) => {
+    assert.equal(String(url), 'https://dnspod.tencentcloudapi.com');
+    actions.push(options.headers['X-TC-Action']);
+    if (options.headers['X-TC-Action'] === 'DescribeRecordList') {
+      return json({
+        Response: {
+          Error: {
+            Code: 'FailedOperation.RecordListEmpty',
+            Message: '记录列表为空。'
+          }
+        }
+      });
+    }
+    return json({ Response: { RecordId: 123 } });
+  };
+
+  const result = await applyDnsSetup(domainFixture(), dnspodCredential(), {
+    records: [{ key: 'dkim', host: 'mh._domainkey.example.com', type: 'TXT', value: 'v=DKIM1; k=rsa; p=abc' }]
+  });
+
+  assert.equal(result.ok, true);
+  assert.equal(result.results[0].detail, 'created');
+  assert.ok(actions.includes('CreateRecord'));
+});
+
 test('dnspod one-click dns falls back to parent zone for subdomain sending domains', async () => {
   const calls = [];
   globalThis.fetch = async (url, options = {}) => {