Skip to content

Commit

Permalink
Merge pull request #101 from richardadonnell/v1.59.4
Browse files Browse the repository at this point in the history
V1.59.4
  • Loading branch information
richardadonnell authored Feb 25, 2025
2 parents 99116a1 + f8b2c64 commit 06e17ef
Show file tree
Hide file tree
Showing 4 changed files with 361 additions and 19 deletions.
126 changes: 117 additions & 9 deletions upwork-job-scraper/background.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,62 @@
// Add global unhandled promise rejection handler
globalThis.addEventListener("unhandledrejection", (event) => {
console.error("Unhandled promise rejection:", event.reason);
logAndReportError("Unhandled promise rejection", event.reason);
// Enhanced error logging for unhandled rejections
const error = event.reason;
const errorObj = {
message: error.message || "Unknown error",
stack: error.stack || "No stack trace available",
context: "Unhandled promise rejection",
timestamp: new Date().toISOString(),
appVersion: chrome.runtime.getManifest().version,
extensionId: chrome.runtime.id || "unknown",
url: self.location?.href || "unknown",
source: "background.js",
};

console.error("Unhandled promise rejection:", errorObj);

// If error is about connection, add more diagnostic info
if (error?.message?.includes("Receiving end does not exist")) {
console.error("Connection error details:", {
extensionState: {
isInitializing,
lastInitializationTime,
jobScrapingEnabled,
checkFrequency,
webhookEnabled,
notificationsEnabled,
},
error: error,
});

// Add diagnostic operation
const diagOpId = startOperation("diagnose-connection-error");
addOperationBreadcrumb(
"Connection error detected",
{
message: error.message,
timeElapsedSinceInit: Date.now() - lastInitializationTime,
},
"error"
);

// Try to log runtime information if available
try {
chrome.runtime.getPlatformInfo((info) => {
addOperationBreadcrumb("Platform info", { platformInfo: info }, "info");
endOperation();
});
} catch (platformError) {
addOperationBreadcrumb(
"Failed to get platform info",
{ error: platformError.message },
"error"
);
endOperation(platformError);
}
}

logAndReportError("Unhandled promise rejection", error);
event.preventDefault(); // Prevent the default handling
});

Expand Down Expand Up @@ -248,18 +303,74 @@ try {
}
});

// Modify the message listener to include error handling
// Modify the message listener to include enhanced error handling
chrome.runtime.onMessage.addListener((message, sender, sendResponse) => {
let handled = false;

// Log all received messages for diagnostic purposes
console.log("Background script received message:", {
type: message.type,
sender: sender.id,
url: sender.url,
timestamp: new Date().toISOString(),
tabId: sender.tab?.id,
});

const handleAsyncOperation = async (operation) => {
try {
// Create a diagnostic context for the operation
const opId = startOperation(`message-handler-${message.type}`);
addOperationBreadcrumb("Starting async operation", {
messageType: message.type,
sender: sender.id,
});

const result = await operation();

addOperationBreadcrumb("Operation completed successfully");
endOperation();

sendResponse({ success: true, ...result });
} catch (error) {
console.error("Error in async operation:", error);
logAndReportError("Error in async operation", error);
sendResponse({ success: false, error: error.message });
console.error(
`Error in async operation for message type '${message.type}':`,
error
);

// Enhanced error details
const errorDetails = {
messageType: message.type,
sender: sender?.id || "unknown",
tabId: sender?.tab?.id,
url: sender?.url,
error: {
name: error.name,
message: error.message,
stack: error.stack,
},
};

// Log error with context
logAndReportError(
`Error in message handler for '${message.type}'`,
error,
errorDetails
);

// Try to end operation if it exists
try {
endOperation(error);
} catch (opError) {
console.error("Error ending operation:", opError);
}

// Send error response
sendResponse({
success: false,
error: error.message,
timestamp: Date.now(),
details: errorDetails,
});
}
};

Expand Down Expand Up @@ -465,9 +576,6 @@ try {
"storage.js"
);

// Import the webhook functions at the top of background.js
importScripts("webhook.js", "activityLog.js");

async function processJobs(newJobs) {
try {
console.log("Starting processJobs with", newJobs.length, "new jobs");
Expand Down
60 changes: 55 additions & 5 deletions upwork-job-scraper/jobScraping.js
Original file line number Diff line number Diff line change
@@ -1,26 +1,76 @@
// Simple lock functions with improved error handling
async function acquireLock() {
try {
const data = await chrome.storage.local.get(["scrapingLock"]);
// Generate a unique lock ID for this operation
const lockId =
"lock_" + Date.now() + "_" + Math.random().toString(36).substring(2, 11);

// Get the current lock state first
const data = await chrome.storage.local.get([
"scrapingLock",
"lockTimestamp",
]);

// Check if there's an existing lock
if (data.scrapingLock) {
// If lock exists, check if it's stale (older than 10 minutes)
const now = Date.now();
const lockTime = data.lockTimestamp || 0;
const lockAgeMinutes = (now - lockTime) / (1000 * 60);

if (lockAgeMinutes < 10) {
// Lock is still valid
addToActivityLog(
"Lock acquisition failed: Another job scraping operation is in progress (running for " +
lockAgeMinutes.toFixed(1) +
" minutes)"
);
return false;
}

// Lock is stale, we'll force release it
addToActivityLog(
"Breaking stale lock (" + lockAgeMinutes.toFixed(1) + " minutes old)"
);
}

// Set the lock with timestamp in a single operation
await chrome.storage.local.set({
scrapingLock: true,
lockTimestamp: Date.now(),
lockId: lockId,
});

// Verify our lock was set (check if our lockId was stored)
const verification = await chrome.storage.local.get(["lockId"]);
if (verification.lockId !== lockId) {
addToActivityLog(
"Lock verification failed: Another process acquired the lock first"
);
return false;
}
await chrome.storage.local.set({ scrapingLock: true });

addToActivityLog("Job scraping lock acquired successfully");
return true;
} catch (error) {
console.error("Error acquiring lock:", error);
addToActivityLog(`Failed to acquire job scraping lock: ${error.message}`);
addToActivityLog("Failed to acquire job scraping lock: " + error.message);
return false;
}
}

async function releaseLock() {
try {
await chrome.storage.local.remove(["scrapingLock"]);
await chrome.storage.local.remove([
"scrapingLock",
"lockTimestamp",
"lockId",
]);
addToActivityLog("Job scraping lock released");
return true;
} catch (error) {
console.error("Error releasing lock:", error);
addToActivityLog(`Failed to release job scraping lock: ${error.message}`);
addToActivityLog("Failed to release job scraping lock: " + error.message);
return false;
}
}
Expand Down
4 changes: 2 additions & 2 deletions upwork-job-scraper/manifest.json
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
{
"manifest_version": 3,
"name": "Upwork Job Scraper + Webhook",
"version": "1.59.1",
"version": "1.59.4",
"description": "Scrapes Upwork jobs and sends them to a webhook",
"permissions": ["storage", "alarms", "notifications", "scripting", "tabs"],
"permissions": ["storage", "alarms", "notifications", "scripting"],
"host_permissions": [
"https://*.upwork.com/*",
"https://www.upwork.com/*",
Expand Down
Loading

0 comments on commit 06e17ef

Please sign in to comment.