🎯 系列目標:用 30 天時間,從零開始打造一個專屬輔大學生的課表生成 Chrome 擴充功能
👨💻 作者:輔大智慧資安 412580084
📅 Day 12:Chrome Extension 實作篇 - 錯誤處理與異常狀況管理
昨天我們建立了 popup 與 background 的消息傳遞機制,今天我們要學習如何處理各種錯誤狀況,讓我們的擴充功能更加穩定可靠!
今天我們要完成:
在 Chrome Extension 開發中,可能遇到的錯誤:
// 常見的錯誤情況
// 1. 找不到 HTML 元素
const button = document.getElementById('nonexistent'); // null
button.click(); // ❌ 錯誤:Cannot read property 'click' of null
// 2. 網路連線失敗
fetch('https://example.com/api')
.then(response => response.json()); // ❌ 可能失敗
// 3. Chrome API 調用失敗
chrome.storage.local.get(['data'], (result) => {
// ❌ 可能因為權限問題失敗
});
// 基本的 try-catch 結構
try {
// 可能出錯的程式碼
const result = riskyOperation();
console.log('操作成功:', result);
} catch (error) {
// 處理錯誤
console.error('操作失敗:', error.message);
} finally {
// 無論成功或失敗都會執行
console.log('操作完成');
}
讓我們改進昨天的 popup.js,加入錯誤處理:
// 改進的按鈕初始化函數
function initializeButtons() {
try {
const generateButton = document.getElementById('generateButton');
const settingsButton = document.getElementById('settingsButton');
if (generateButton) {
generateButton.addEventListener('click', handleGenerateClick);
console.log('✅ 生成按鈕事件已綁定');
} else {
throw new Error('找不到生成按鈕元素');
}
if (settingsButton) {
settingsButton.addEventListener('click', handleSettingsClick);
console.log('✅ 設定按鈕事件已綁定');
} else {
throw new Error('找不到設定按鈕元素');
}
} catch (error) {
console.error('❌ 按鈕初始化失敗:', error.message);
showStatus('介面初始化失敗', 'error');
}
}
// 使用錯誤處理的生成課表函數
function handleGenerateClick() {
console.log('🔘 生成課表按鈕被點擊');
try {
setButtonLoading('generateButton', '⏳ 處理中...');
showLoadingStatus('正在與背景腳本溝通...');
// 簡化的消息發送
chrome.runtime.sendMessage({
action: 'generateSchedule',
data: { timestamp: new Date().toISOString() }
}, (response) => {
// 恢復按鈕狀態
resetButton('generateButton');
// 檢查 Chrome API 錯誤
if (chrome.runtime.lastError) {
showStatus('連線失敗,請重新載入擴充功能', 'error');
console.error('❌ Chrome API 錯誤:', chrome.runtime.lastError);
return;
}
if (response && response.success) {
// 處理成功
showStatus('課表生成成功!', 'success');
console.log('✅ Background 回應:', response);
} else {
// 處理業務邏輯錯誤
const errorMsg = response?.error || '未知錯誤';
showStatus('課表生成失敗:' + errorMsg, 'error');
console.error('❌ 業務邏輯錯誤:', errorMsg);
}
});
} catch (error) {
// 處理同步錯誤
resetButton('generateButton');
showStatus('系統錯誤,請重新啟動瀏覽器', 'error');
console.error('❌ 同步錯誤:', error);
}
}
測試正常功能:
測試錯誤情況:
📁 fju-schedule-extension/
├── 📄 manifest.json ← 擴充功能設定
├── 📄 background.js ← 背景腳本
├── 📄 popup.html ← 使用者介面
└── 📄 popup.js ← 彈出視窗邏輯(今天加入錯誤處理)
🔗 知識銜接:今天我們讓程式更加穩定可靠,明天將學習 Content Script 的基礎概念,開始接觸網頁內容操作。
🎯 下集預告:Day 13 - Content Script 基礎介紹 🌐