This commit is contained in:
Omar Najjar 2025-04-13 04:41:44 +10:00
parent 1b3c0db99f
commit c785511f3f
2 changed files with 107 additions and 36 deletions

View file

@ -640,8 +640,14 @@ async function safeFetch(url, options = {}) {
clearTimeout(timeoutId);
// Check for successful response
if (!response.ok) {
const errorText = await response.text();
if (response.status < 200 || response.status >= 300) {
let errorText;
try {
const errorData = await response.json();
errorText = errorData.error || JSON.stringify(errorData);
} catch (e) {
errorText = await response.text();
}
// Check if this is a Cloudflare error
if (errorText.includes('Cloudflare') || errorText.includes('cf-error')) {
@ -663,7 +669,12 @@ async function safeFetch(url, options = {}) {
throw new Error(`HTTP error! status: ${response.status}, message: ${errorText}`);
}
return await response.json();
try {
return await response.json();
} catch (jsonError) {
console.error('Error parsing JSON response:', jsonError);
throw new Error('Invalid response format from server');
}
} catch (error) {
console.error('Fetch Error:', {
message: error.message,
@ -692,7 +703,7 @@ async function safeFetch(url, options = {}) {
const sortBy = sortSelect ? sortSelect.value : 'newest';
// Log the full request URL and parameters
const requestUrl = `${API_BASE_URL}/proposals?sortBy=${sortBy}&userId=${currentUser.id}`;
const requestUrl = `${API_BASE_URL}/proposals?sortBy=${sortBy}&userId=${currentUser?.id || 'anonymous'}`;
console.log('Fetching proposals from:', requestUrl);
console.log('Current user:', currentUser);
@ -711,13 +722,35 @@ async function safeFetch(url, options = {}) {
console.log('Response headers:', Object.fromEntries(response.headers.entries()));
if (!response.ok) {
const errorText = await response.text();
console.error('Error response:', errorText);
let errorText;
try {
const errorData = await response.json();
console.error('Error response JSON:', errorData);
errorText = errorData.error || errorData.details?.message || JSON.stringify(errorData);
} catch (e) {
errorText = await response.text();
console.error('Error response text:', errorText);
}
throw new Error(`HTTP error! status: ${response.status}, message: ${errorText}`);
}
const data = await response.json();
console.log('Proposals data:', data);
let data;
try {
data = await response.json();
} catch (jsonError) {
console.error('Error parsing JSON response:', jsonError);
throw new Error('Invalid JSON response from server');
}
console.log('Proposals data received:', {
count: data?.data?.length || 0,
pagination: data?.pagination
});
if (!data || !data.data || !Array.isArray(data.data)) {
console.error('Invalid data structure:', data);
throw new Error('Invalid data structure received from server');
}
renderProposals(data);
} catch (error) {
@ -2259,34 +2292,49 @@ async function submitComment(proposalId, commentText) {
console.log(`Submitting comment for proposal ${proposalId}: ${commentText.substring(0, 20)}...`);
return safeFetch(`${API_BASE_URL}/comments`, {
method: 'POST',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify({
proposalId: proposalId,
userId: currentUser.id,
commentText: commentText
})
})
.then(response => {
if (!response.ok) {
throw new Error('Failed to post comment');
try {
const response = await fetch(`${API_BASE_URL}/comments`, {
method: 'POST',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify({
proposalId: proposalId,
userId: currentUser.id,
commentText: commentText
})
});
console.log("Comment submission response status:", response.status);
if (response.status >= 200 && response.status < 300) {
// Successfully created comment
const data = await response.json();
console.log("Comment created successfully:", data);
loadComments(proposalId);
updateCommentCount(proposalId);
showToastMessage('Comment posted!', '#11cc77');
return data;
} else {
// Server returned an error
let errorMessage;
try {
const errorData = await response.json();
errorMessage = errorData.error || 'Unknown server error';
} catch (e) {
errorMessage = await response.text() || 'Failed to post comment';
}
console.error('Error posting comment:', errorMessage);
showToastMessage('Failed to post comment', '#ff0099');
throw new Error(errorMessage);
}
return response.json();
})
.then(data => {
loadComments(proposalId);
updateCommentCount(proposalId);
showToastMessage('Comment posted!', '#11cc77');
return data;
})
.catch(error => {
console.error('Error posting comment:', error);
} catch (error) {
console.error('Network or processing error:', error);
showToastMessage('Failed to post comment', '#ff0099');
throw error;
});
}
}
// Function to check if comment input is not empty

View file

@ -31,6 +31,8 @@ function createResponse(body, status = 200, cacheDuration = 60*60*24) {
headers['Cache-Control'] = 'no-store';
}
// Create a standard Response object
// This ensures properties like 'ok' are properly set based on status code
return new Response(JSON.stringify(body), {
status,
headers
@ -1033,6 +1035,9 @@ async function getProposals(request, env) {
MAX_PAGE_SIZE
);
const offset = (page - 1) * limit;
const sortBy = url.searchParams.get('sortBy') || 'newest';
console.log(`Getting proposals with sorting: ${sortBy}`);
// Define the base query
let query = `
@ -1045,26 +1050,44 @@ async function getProposals(request, env) {
(SELECT COUNT(DISTINCT pd.user_id) FROM petition_details pd WHERE pd.proposal_id = p.id AND pd.verified = 1) as verified_petitioners
FROM proposals p
JOIN users u ON p.author_id = u.id
ORDER BY p.timestamp DESC
`;
// Add sorting
if (sortBy === 'newest') {
query += ` ORDER BY p.timestamp DESC`;
} else if (sortBy === 'oldest') {
query += ` ORDER BY p.timestamp ASC`;
} else if (sortBy === 'popular') {
query += ` ORDER BY upvotes DESC, p.timestamp DESC`;
} else if (sortBy === 'controversial') {
query += ` ORDER BY (upvotes + downvotes) DESC, ABS(upvotes - downvotes) ASC, p.timestamp DESC`;
} else {
// Default to newest
query += ` ORDER BY p.timestamp DESC`;
}
// Add pagination
query += ` LIMIT ? OFFSET ?`;
console.log(`Executing query with pagination: limit=${limit}, offset=${offset}`);
// Execute the query
const proposals = await env.DB.prepare(query).bind(limit, offset).all();
console.log(`Retrieved ${proposals.results?.length || 0} proposals`);
// Add pagination info to response
return createResponse({
data: proposals.results,
pagination: {
page,
limit,
total: proposals.results.length,
hasMore: proposals.results.length === limit
total: proposals.results?.length || 0,
hasMore: proposals.results?.length === limit
}
});
} catch (error) {
console.error('Error retrieving proposals:', error);
return createResponse({
error: 'Failed to retrieve proposals',
details: logError(error, { action: 'get_proposals' })