fix: Add nested try-catch for JSON parsing and improve error handling

style: Format code with consistent indentation and line breaks
This commit is contained in:
Robin Tuszik 2024-12-11 21:10:00 +01:00
parent 5583d04ac0
commit aedda20210

View file

@ -1,13 +1,19 @@
import { Plugin, Notice } from "obsidian";
import { AutoClassifierSettingTab, AutoClassifierSettings, DEFAULT_SETTINGS, OutLocation, OutType} from "src/settings";
import {
AutoClassifierSettingTab,
AutoClassifierSettings,
DEFAULT_SETTINGS,
OutLocation,
OutType,
} from "src/settings";
import { ViewManager } from "src/view-manager";
import { ChatGPT } from 'src/api';
import { ChatGPT } from "src/api";
enum InputType {
SelectedArea,
Title,
FrontMatter,
Content
Content,
}
export default class AutoClassifierPlugin extends Plugin {
@ -19,32 +25,32 @@ export default class AutoClassifierPlugin extends Plugin {
// Commands
this.addCommand({
id: 'classify-tag-selected',
name: 'Classify tag from Selected Area',
id: "classify-tag-selected",
name: "Classify tag from Selected Area",
callback: async () => {
await this.runClassifyTag(InputType.SelectedArea);
}
},
});
this.addCommand({
id: 'classify-tag-title',
name: 'Classify tag from Note Title',
id: "classify-tag-title",
name: "Classify tag from Note Title",
callback: async () => {
await this.runClassifyTag(InputType.Title);
}
},
});
this.addCommand({
id: 'classify-tag-frontmatter',
name: 'Classify tag from FrontMatter',
id: "classify-tag-frontmatter",
name: "Classify tag from FrontMatter",
callback: async () => {
await this.runClassifyTag(InputType.FrontMatter);
}
},
});
this.addCommand({
id: 'classify-tag-content',
name: 'Classify tag from Note Content',
id: "classify-tag-content",
name: "Classify tag from Note Content",
callback: async () => {
await this.runClassifyTag(InputType.Content);
}
},
});
this.addSettingTab(new AutoClassifierSettingTab(this.app, this));
@ -57,18 +63,17 @@ export default class AutoClassifierPlugin extends Plugin {
await this.saveData(this.settings);
}
async onunload() {
}
async onunload() {}
// create loading spin in the Notice message
createLoadingNotice(text: string, number = 10000): Notice {
const notice = new Notice('', number);
const loadingContainer = document.createElement('div');
loadingContainer.addClass('loading-container');
const notice = new Notice("", number);
const loadingContainer = document.createElement("div");
loadingContainer.addClass("loading-container");
const loadingIcon = document.createElement('div');
loadingIcon.addClass('loading-icon');
const loadingText = document.createElement('span');
const loadingIcon = document.createElement("div");
loadingIcon.addClass("loading-icon");
const loadingText = document.createElement("span");
loadingText.textContent = text;
//@ts-ignore
notice.noticeEl.empty();
@ -96,28 +101,25 @@ export default class AutoClassifierPlugin extends Plugin {
// ------- [API Key check] -------
if (!this.settings.apiKey) {
new Notice(`${this.manifest.name}: You shuld input your API Key`);
return null
return null;
}
// ------- [Input] -------
const refs = this.settings.commandOption.refs;
// reference check
if (this.settings.commandOption.useRef && (!refs || refs.length == 0)) {
new Notice(`${this.manifest.name}: no reference tags`);
return null
return null;
}
// Set Input
let input: string | null = '';
// Set Input
let input: string | null = "";
if (inputType == InputType.SelectedArea) {
input = await this.viewManager.getSelection();
}
else if (inputType == InputType.Title) {
} else if (inputType == InputType.Title) {
input = await this.viewManager.getTitle();
}
else if (inputType == InputType.FrontMatter) {
} else if (inputType == InputType.FrontMatter) {
input = await this.viewManager.getFrontMatter();
}
else if (inputType == InputType.Content) {
} else if (inputType == InputType.Content) {
input = await this.viewManager.getContent();
}
@ -129,17 +131,20 @@ export default class AutoClassifierPlugin extends Plugin {
// Replace {{input}}, {{reference}}
let user_prompt = this.settings.commandOption.prmpt_template;
user_prompt = user_prompt.replace('{{input}}', input);
user_prompt = user_prompt.replace('{{reference}}', refs.join(','));
user_prompt = user_prompt.replace('{{max_suggestions}}', String(this.settings.commandOption.max_suggestions));
user_prompt = user_prompt.replace("{{input}}", input);
user_prompt = user_prompt.replace("{{reference}}", refs.join(","));
user_prompt = user_prompt.replace(
"{{max_suggestions}}",
String(this.settings.commandOption.max_suggestions),
);
const system_role = this.settings.commandOption.prmpt_template;
// ------- [API Processing] -------
// Call API
const responseRaw = await ChatGPT.callAPI(
system_role,
user_prompt,
system_role,
user_prompt,
this.settings.apiKey,
this.settings.commandOption.model,
this.settings.commandOption.max_tokens,
@ -150,48 +155,77 @@ export default class AutoClassifierPlugin extends Plugin {
this.settings.baseURL,
);
try {
const response = JSON.parse(responseRaw);
const resReliability = response.reliability;
const resOutputs = response.outputs;
try {
const response = JSON.parse(responseRaw);
const resReliability = response.reliability;
const resOutputs = response.outputs;
// Validate response format
if (!Array.isArray(resOutputs)) {
new Notice(`${this.manifest.name}: output format error (expected array)`);
// Validate response format
if (!Array.isArray(resOutputs)) {
new Notice(`${this.manifest.name}: output format error (expected array)`);
return null;
}
// Avoid low reliability
if (resReliability <= 0.2) {
new Notice(
`${this.manifest.name}: response has low reliability (${resReliability})`,
);
return null;
}
// ------- [Add Tags] -------
for (const resOutput of resOutputs) {
// Output Type 1. [Tag Case] + Output Type 2. [Wikilink Case]
if (
commandOption.outType == OutType.Tag ||
commandOption.outType == OutType.Wikilink
) {
if (commandOption.outLocation == OutLocation.Cursor) {
this.viewManager.insertAtCursor(
resOutput,
commandOption.overwrite,
commandOption.outType,
commandOption.outPrefix,
commandOption.outSuffix,
);
} else if (commandOption.outLocation == OutLocation.ContentTop) {
this.viewManager.insertAtContentTop(
resOutput,
commandOption.outType,
commandOption.outPrefix,
commandOption.outSuffix,
);
}
}
// Output Type 3. [Frontmatter Case]
else if (commandOption.outType == OutType.FrontMatter) {
this.viewManager.insertAtFrontMatter(
commandOption.key,
resOutput,
commandOption.overwrite,
commandOption.outPrefix,
commandOption.outSuffix,
);
}
// Output Type 4. [Title]
else if (commandOption.outType == OutType.Title) {
this.viewManager.insertAtTitle(
resOutput,
commandOption.overwrite,
commandOption.outPrefix,
commandOption.outSuffix,
);
}
}
new Notice(`${this.manifest.name}: classified with ${resOutputs.length} tags`);
} catch (error) {
new Notice(`${this.manifest.name}: JSON parsing error - ${error}`);
return null;
}
// Avoid low reliability
if (resReliability <= 0.2) {
new Notice(`${this.manifest.name}: response has low reliability (${resReliability})`);
return null;
}
// ------- [Add Tags] -------
for (const resOutput of resOutputs) {
// Output Type 1. [Tag Case] + Output Type 2. [Wikilink Case]
if (commandOption.outType == OutType.Tag || commandOption.outType == OutType.Wikilink) {
if (commandOption.outLocation == OutLocation.Cursor) {
this.viewManager.insertAtCursor(resOutput, commandOption.overwrite, commandOption.outType, commandOption.outPrefix, commandOption.outSuffix);
}
else if (commandOption.outLocation == OutLocation.ContentTop) {
this.viewManager.insertAtContentTop(resOutput, commandOption.outType, commandOption.outPrefix, commandOption.outSuffix);
}
}
// Output Type 3. [Frontmatter Case]
else if (commandOption.outType == OutType.FrontMatter) {
this.viewManager.insertAtFrontMatter(commandOption.key, resOutput, commandOption.overwrite, commandOption.outPrefix, commandOption.outSuffix);
}
// Output Type 4. [Title]
else if (commandOption.outType == OutType.Title) {
this.viewManager.insertAtTitle(resOutput, commandOption.overwrite, commandOption.outPrefix, commandOption.outSuffix);
}
}
new Notice(`${this.manifest.name}: classified with ${resOutputs.length} tags`);
} catch (error) {
new Notice(`${this.manifest.name}: ${error}`);
return null;
}
}
}