tthr 0.3.20 → 0.3.21
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.js +38 -20
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -35,6 +35,42 @@ import ora from "ora";
|
|
|
35
35
|
import fs from "fs-extra";
|
|
36
36
|
import path from "path";
|
|
37
37
|
import * as esbuild from "esbuild";
|
|
38
|
+
async function describeHttpError(response, action) {
|
|
39
|
+
const status = response.status;
|
|
40
|
+
const contentType = response.headers.get("content-type") ?? "";
|
|
41
|
+
const text = await response.text().catch(() => "");
|
|
42
|
+
if (contentType.includes("application/json")) {
|
|
43
|
+
try {
|
|
44
|
+
const json = JSON.parse(text);
|
|
45
|
+
if (typeof json?.error === "string") return json.error;
|
|
46
|
+
} catch {
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
const looksLikeHtml = contentType.includes("text/html") || /^\s*<(!doctype|html)/i.test(text);
|
|
50
|
+
if (looksLikeHtml) {
|
|
51
|
+
const hint = (() => {
|
|
52
|
+
switch (status) {
|
|
53
|
+
case 401:
|
|
54
|
+
case 403:
|
|
55
|
+
return "Authentication failed or insufficient permissions. Try `tthr login` first.";
|
|
56
|
+
case 404:
|
|
57
|
+
return `Route or resource not found. Common causes: wrong project ID, environment doesn't exist on this server, or TETHER_API_URL points at the wrong host.`;
|
|
58
|
+
case 429:
|
|
59
|
+
return "Rate-limited by the server or upstream proxy. Wait a moment and retry.";
|
|
60
|
+
case 502:
|
|
61
|
+
case 503:
|
|
62
|
+
case 504:
|
|
63
|
+
return "Server is unreachable, restarting, or under load. Check status and retry.";
|
|
64
|
+
default:
|
|
65
|
+
return `Upstream proxy returned a generic ${status} page (likely a Cloudflare / nginx fallback).`;
|
|
66
|
+
}
|
|
67
|
+
})();
|
|
68
|
+
return `Failed to ${action}: ${hint} (HTTP ${status})`;
|
|
69
|
+
}
|
|
70
|
+
const trimmed = text.trim();
|
|
71
|
+
if (trimmed) return `${trimmed.slice(0, 300)}${trimmed.length > 300 ? "\u2026" : ""} (HTTP ${status})`;
|
|
72
|
+
return `HTTP ${status}: ${response.statusText || "request failed"}`;
|
|
73
|
+
}
|
|
38
74
|
async function deployCommand(options) {
|
|
39
75
|
const credentials = await requireAuth();
|
|
40
76
|
const configPath = path.resolve(process.cwd(), "tether.config.ts");
|
|
@@ -146,16 +182,7 @@ async function deploySchemaToServer(projectId, token, schemaPath, environment, d
|
|
|
146
182
|
console.log(chalk.dim(` Response: ${response.status} ${response.statusText}`));
|
|
147
183
|
console.log(chalk.dim(` Content-Type: ${response.headers.get("content-type")}`));
|
|
148
184
|
if (!response.ok) {
|
|
149
|
-
|
|
150
|
-
console.log(chalk.dim(` Body: ${text.slice(0, 500)}`));
|
|
151
|
-
let errorMessage;
|
|
152
|
-
try {
|
|
153
|
-
const error = JSON.parse(text);
|
|
154
|
-
errorMessage = error.error || `HTTP ${response.status}`;
|
|
155
|
-
} catch {
|
|
156
|
-
errorMessage = text || `HTTP ${response.status}: ${response.statusText}`;
|
|
157
|
-
}
|
|
158
|
-
throw new Error(errorMessage);
|
|
185
|
+
throw new Error(await describeHttpError(response, "deploy schema"));
|
|
159
186
|
}
|
|
160
187
|
spinner.succeed(`Schema deployed (${tables.length} table(s))`);
|
|
161
188
|
} catch (error) {
|
|
@@ -269,16 +296,7 @@ ${helperSource}`;
|
|
|
269
296
|
console.log(chalk.dim(` Response: ${response.status} ${response.statusText}`));
|
|
270
297
|
console.log(chalk.dim(` Content-Type: ${response.headers.get("content-type")}`));
|
|
271
298
|
if (!response.ok) {
|
|
272
|
-
|
|
273
|
-
console.log(chalk.dim(` Body: ${text.slice(0, 500)}`));
|
|
274
|
-
let errorMessage;
|
|
275
|
-
try {
|
|
276
|
-
const error = JSON.parse(text);
|
|
277
|
-
errorMessage = error.error || `HTTP ${response.status}`;
|
|
278
|
-
} catch {
|
|
279
|
-
errorMessage = text || `HTTP ${response.status}: ${response.statusText}`;
|
|
280
|
-
}
|
|
281
|
-
throw new Error(errorMessage);
|
|
299
|
+
throw new Error(await describeHttpError(response, "deploy functions"));
|
|
282
300
|
}
|
|
283
301
|
spinner.succeed(`Functions deployed (${functions.length} function(s))`);
|
|
284
302
|
const queries = functions.filter((f) => f.type === "query");
|