mirror of
https://github.com/vrtmrz/obsidian-livesync.git
synced 2026-07-14 00:26:00 +00:00
Improved: show details of TypeError using Obsidian API.
This commit is contained in:
@@ -1,5 +1,5 @@
|
|||||||
import { AbstractObsidianModule, type IObsidianModule } from "../AbstractObsidianModule.ts";
|
import { AbstractObsidianModule, type IObsidianModule } from "../AbstractObsidianModule.ts";
|
||||||
import { LOG_LEVEL_DEBUG, LOG_LEVEL_VERBOSE } from "octagonal-wheels/common/logger";
|
import { LOG_LEVEL_DEBUG, LOG_LEVEL_NOTICE, LOG_LEVEL_VERBOSE } from "octagonal-wheels/common/logger";
|
||||||
import { Notice, requestUrl, type RequestUrlParam, type RequestUrlResponse } from "../../deps.ts";
|
import { Notice, requestUrl, type RequestUrlParam, type RequestUrlResponse } from "../../deps.ts";
|
||||||
import { type EntryDoc, type FilePathWithPrefix } from "../../lib/src/common/types.ts";
|
import { type EntryDoc, type FilePathWithPrefix } from "../../lib/src/common/types.ts";
|
||||||
import { getPathFromTFile } from "../../common/utils.ts";
|
import { getPathFromTFile } from "../../common/utils.ts";
|
||||||
@@ -47,6 +47,58 @@ export class ModuleObsidianAPI extends AbstractObsidianModule implements IObsidi
|
|||||||
return !this.last_successful_post;
|
return !this.last_successful_post;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async fetchByAPI(
|
||||||
|
url: string,
|
||||||
|
localURL: string,
|
||||||
|
method: string,
|
||||||
|
authHeader: string,
|
||||||
|
opts?: RequestInit
|
||||||
|
): Promise<Response> {
|
||||||
|
const body = opts?.body as string;
|
||||||
|
|
||||||
|
const transformedHeaders = { ...(opts?.headers as Record<string, string>) };
|
||||||
|
if (authHeader != "") transformedHeaders["authorization"] = authHeader;
|
||||||
|
delete transformedHeaders["host"];
|
||||||
|
delete transformedHeaders["Host"];
|
||||||
|
delete transformedHeaders["content-length"];
|
||||||
|
delete transformedHeaders["Content-Length"];
|
||||||
|
const requestParam: RequestUrlParam = {
|
||||||
|
url,
|
||||||
|
method: opts?.method,
|
||||||
|
body: body,
|
||||||
|
headers: transformedHeaders,
|
||||||
|
contentType: "application/json",
|
||||||
|
// contentType: opts.headers,
|
||||||
|
};
|
||||||
|
const size = body ? ` (${body.length})` : "";
|
||||||
|
try {
|
||||||
|
this.plugin.requestCount.value = this.plugin.requestCount.value + 1;
|
||||||
|
const r = await fetchByAPI(requestParam);
|
||||||
|
if (method == "POST" || method == "PUT") {
|
||||||
|
this.last_successful_post = r.status - (r.status % 100) == 200;
|
||||||
|
} else {
|
||||||
|
this.last_successful_post = true;
|
||||||
|
}
|
||||||
|
this._log(`HTTP:${method}${size} to:${localURL} -> ${r.status}`, LOG_LEVEL_DEBUG);
|
||||||
|
|
||||||
|
return new Response(r.arrayBuffer, {
|
||||||
|
headers: r.headers,
|
||||||
|
status: r.status,
|
||||||
|
statusText: `${r.status}`,
|
||||||
|
});
|
||||||
|
} catch (ex) {
|
||||||
|
this._log(`HTTP:${method}${size} to:${localURL} -> failed`, LOG_LEVEL_VERBOSE);
|
||||||
|
// limit only in bulk_docs.
|
||||||
|
if (url.toString().indexOf("_bulk_docs") !== -1) {
|
||||||
|
this.last_successful_post = false;
|
||||||
|
}
|
||||||
|
this._log(ex);
|
||||||
|
throw ex;
|
||||||
|
} finally {
|
||||||
|
this.plugin.responseCount.value = this.plugin.responseCount.value + 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
async $$connectRemoteCouchDB(
|
async $$connectRemoteCouchDB(
|
||||||
uri: string,
|
uri: string,
|
||||||
auth: { username: string; password: string },
|
auth: { username: string; password: string },
|
||||||
@@ -87,88 +139,74 @@ export class ModuleObsidianAPI extends AbstractObsidianModule implements IObsidi
|
|||||||
}
|
}
|
||||||
size = ` (${opts_length})`;
|
size = ` (${opts_length})`;
|
||||||
}
|
}
|
||||||
if (!disableRequestURI && typeof url == "string" && typeof (opts?.body ?? "") == "string") {
|
try {
|
||||||
const body = opts?.body as string;
|
if (!disableRequestURI && typeof url == "string" && typeof (opts?.body ?? "") == "string") {
|
||||||
|
return await this.fetchByAPI(url, localURL, method, authHeader, opts);
|
||||||
const transformedHeaders = { ...(opts?.headers as Record<string, string>) };
|
}
|
||||||
if (authHeader != "") transformedHeaders["authorization"] = authHeader;
|
// --> native Fetch API.
|
||||||
delete transformedHeaders["host"];
|
|
||||||
delete transformedHeaders["Host"];
|
|
||||||
delete transformedHeaders["content-length"];
|
|
||||||
delete transformedHeaders["Content-Length"];
|
|
||||||
const requestParam: RequestUrlParam = {
|
|
||||||
url,
|
|
||||||
method: opts?.method,
|
|
||||||
body: body,
|
|
||||||
headers: transformedHeaders,
|
|
||||||
contentType: "application/json",
|
|
||||||
// contentType: opts.headers,
|
|
||||||
};
|
|
||||||
|
|
||||||
try {
|
try {
|
||||||
|
if (this.settings.enableDebugTools) {
|
||||||
|
// Issue #407
|
||||||
|
(opts!.headers as Headers).append("ngrok-skip-browser-warning", "123");
|
||||||
|
}
|
||||||
this.plugin.requestCount.value = this.plugin.requestCount.value + 1;
|
this.plugin.requestCount.value = this.plugin.requestCount.value + 1;
|
||||||
const r = await fetchByAPI(requestParam);
|
const response: Response = await fetch(url, opts);
|
||||||
if (method == "POST" || method == "PUT") {
|
if (method == "POST" || method == "PUT") {
|
||||||
this.last_successful_post = r.status - (r.status % 100) == 200;
|
this.last_successful_post = response.ok;
|
||||||
} else {
|
} else {
|
||||||
this.last_successful_post = true;
|
this.last_successful_post = true;
|
||||||
}
|
}
|
||||||
this._log(`HTTP:${method}${size} to:${localURL} -> ${r.status}`, LOG_LEVEL_DEBUG);
|
this._log(`HTTP:${method}${size} to:${localURL} -> ${response.status}`, LOG_LEVEL_DEBUG);
|
||||||
|
if (Math.floor(response.status / 100) !== 2) {
|
||||||
return new Response(r.arrayBuffer, {
|
if (response.status == 404) {
|
||||||
headers: r.headers,
|
if (method === "GET" && localURL.indexOf("/_local/") === -1) {
|
||||||
status: r.status,
|
this._log(
|
||||||
statusText: `${r.status}`,
|
`Just checkpoint or some server information has been missing. The 404 error shown above is not an error.`,
|
||||||
});
|
LOG_LEVEL_VERBOSE
|
||||||
} catch (ex) {
|
);
|
||||||
this._log(`HTTP:${method}${size} to:${localURL} -> failed`, LOG_LEVEL_VERBOSE);
|
}
|
||||||
// limit only in bulk_docs.
|
} else {
|
||||||
if (url.toString().indexOf("_bulk_docs") !== -1) {
|
const r = response.clone();
|
||||||
this.last_successful_post = false;
|
this._log(
|
||||||
}
|
`The request may have failed. The reason sent by the server: ${r.status}: ${r.statusText}`,
|
||||||
this._log(ex);
|
LOG_LEVEL_NOTICE
|
||||||
throw ex;
|
);
|
||||||
} finally {
|
try {
|
||||||
this.plugin.responseCount.value = this.plugin.responseCount.value + 1;
|
const result = await r.text();
|
||||||
}
|
this._log(result, LOG_LEVEL_VERBOSE);
|
||||||
}
|
} catch (_) {
|
||||||
|
this._log("Cloud not fetch response body", LOG_LEVEL_VERBOSE);
|
||||||
try {
|
this._log(_, LOG_LEVEL_VERBOSE);
|
||||||
if (this.settings.enableDebugTools) {
|
}
|
||||||
// Issue #407
|
|
||||||
(opts!.headers as Headers).append("ngrok-skip-browser-warning", "123");
|
|
||||||
}
|
|
||||||
this.plugin.requestCount.value = this.plugin.requestCount.value + 1;
|
|
||||||
const response: Response = await fetch(url, opts);
|
|
||||||
if (method == "POST" || method == "PUT") {
|
|
||||||
this.last_successful_post = response.ok;
|
|
||||||
} else {
|
|
||||||
this.last_successful_post = true;
|
|
||||||
}
|
|
||||||
this._log(`HTTP:${method}${size} to:${localURL} -> ${response.status}`, LOG_LEVEL_DEBUG);
|
|
||||||
if (Math.floor(response.status / 100) !== 2) {
|
|
||||||
if (method != "GET" && localURL.indexOf("/_local/") === -1 && !localURL.endsWith("/")) {
|
|
||||||
const r = response.clone();
|
|
||||||
this._log(
|
|
||||||
`The request may have failed. The reason sent by the server: ${r.status}: ${r.statusText}`
|
|
||||||
);
|
|
||||||
|
|
||||||
try {
|
|
||||||
this._log(await (await r.blob()).text(), LOG_LEVEL_VERBOSE);
|
|
||||||
} catch (_) {
|
|
||||||
this._log("Cloud not parse response", LOG_LEVEL_VERBOSE);
|
|
||||||
this._log(_, LOG_LEVEL_VERBOSE);
|
|
||||||
}
|
}
|
||||||
} else {
|
|
||||||
this._log(
|
|
||||||
`Just checkpoint or some server information has been missing. The 404 error shown above is not an error.`,
|
|
||||||
LOG_LEVEL_VERBOSE
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
return response;
|
||||||
|
} catch (ex) {
|
||||||
|
if (ex instanceof TypeError) {
|
||||||
|
this._log(
|
||||||
|
"Failed to fetch by native fetch API. Trying to fetch by API to get more information."
|
||||||
|
);
|
||||||
|
const resp2 = await this.fetchByAPI(url.toString(), localURL, method, authHeader, opts);
|
||||||
|
if (resp2.status / 100 == 2) {
|
||||||
|
this._log(
|
||||||
|
"The request was successful by API. But the native fetch API failed! Please check CORS settings on the remote database!. While this condition, you cannot enable LiveSync",
|
||||||
|
LOG_LEVEL_NOTICE
|
||||||
|
);
|
||||||
|
return resp2;
|
||||||
|
}
|
||||||
|
const r2 = resp2.clone();
|
||||||
|
const msg = await r2.text();
|
||||||
|
this._log(`Failed to fetch by API. ${resp2.status}: ${msg}`, LOG_LEVEL_NOTICE);
|
||||||
|
return resp2;
|
||||||
|
}
|
||||||
|
throw ex;
|
||||||
}
|
}
|
||||||
return response;
|
} catch (ex: any) {
|
||||||
} catch (ex) {
|
|
||||||
this._log(`HTTP:${method}${size} to:${localURL} -> failed`, LOG_LEVEL_VERBOSE);
|
this._log(`HTTP:${method}${size} to:${localURL} -> failed`, LOG_LEVEL_VERBOSE);
|
||||||
|
const msg = ex instanceof Error ? `${ex?.name}:${ex?.message}` : ex?.toString();
|
||||||
|
this._log(`Failed to fetch: ${msg}`, LOG_LEVEL_NOTICE);
|
||||||
|
this._log(ex, LOG_LEVEL_VERBOSE);
|
||||||
// limit only in bulk_docs.
|
// limit only in bulk_docs.
|
||||||
if (url.toString().indexOf("_bulk_docs") !== -1) {
|
if (url.toString().indexOf("_bulk_docs") !== -1) {
|
||||||
this.last_successful_post = false;
|
this.last_successful_post = false;
|
||||||
@@ -178,6 +216,7 @@ export class ModuleObsidianAPI extends AbstractObsidianModule implements IObsidi
|
|||||||
} finally {
|
} finally {
|
||||||
this.plugin.responseCount.value = this.plugin.responseCount.value + 1;
|
this.plugin.responseCount.value = this.plugin.responseCount.value + 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
// return await fetch(url, opts);
|
// return await fetch(url, opts);
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
@@ -195,11 +234,7 @@ export class ModuleObsidianAPI extends AbstractObsidianModule implements IObsidi
|
|||||||
const info = await db.info();
|
const info = await db.info();
|
||||||
return { db: db, info: info };
|
return { db: db, info: info };
|
||||||
} catch (ex: any) {
|
} catch (ex: any) {
|
||||||
let msg = `${ex?.name}:${ex?.message}`;
|
const msg = `${ex?.name}:${ex?.message}`;
|
||||||
if (ex?.name == "TypeError" && ex?.message == "Failed to fetch") {
|
|
||||||
msg +=
|
|
||||||
"\n**Note** This error caused by many reasons. The only sure thing is you didn't touch the server.\nTo check details, open inspector.";
|
|
||||||
}
|
|
||||||
this._log(ex, LOG_LEVEL_VERBOSE);
|
this._log(ex, LOG_LEVEL_VERBOSE);
|
||||||
return msg;
|
return msg;
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user