Skip to content

Commit daba1b1

Browse files
committed
fix: resolve public-api transaction timeout, dashboard empty table, and sdk parsing error
1 parent 38ac081 commit daba1b1

3 files changed

Lines changed: 39 additions & 49 deletions

File tree

apps/public-api/src/controllers/data.controller.js

Lines changed: 28 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -534,54 +534,37 @@ module.exports.updateSingleData = async (req, res, next) => {
534534

535535
// Only enforce quota for internal databases
536536
if (!project.resources.db.isExternal) {
537-
const session = await mongoose.startSession();
538-
session.startTransaction();
539-
540-
try {
541-
// 1. Fetch existing doc securely within transaction
542-
const existingDoc = await Model.findOne(queryFilter).session(session).lean();
543-
if (!existingDoc) {
544-
await session.abortTransaction();
545-
session.endSession();
546-
return next(new AppError(404, "Document not found."));
547-
}
537+
// 1. Fetch existing doc securely
538+
const existingDoc = await Model.findOne(queryFilter).lean();
539+
if (!existingDoc) {
540+
return next(new AppError(404, "Document not found."));
541+
}
548542

549-
// 2. Calculate sizes
550-
const oldSize = mongoose.mongo.BSON.calculateObjectSize(existingDoc);
551-
const simulatedNewDoc = { ...existingDoc, ...sanitizedData };
552-
const newSize = mongoose.mongo.BSON.calculateObjectSize(simulatedNewDoc);
553-
const sizeDelta = newSize - oldSize;
554-
555-
// 3. Enforce quota if size is increasing
556-
if (sizeDelta > 0) {
557-
if ((project.databaseUsed || 0) + sizeDelta > project.databaseLimit) {
558-
await session.abortTransaction();
559-
session.endSession();
560-
return next(new AppError(403, "Storage quota exceeded. Please upgrade your plan."));
561-
}
562-
}
543+
// 2. Calculate sizes
544+
const oldSize = mongoose.mongo.BSON.calculateObjectSize(existingDoc);
545+
const simulatedNewDoc = { ...existingDoc, ...sanitizedData };
546+
const newSize = mongoose.mongo.BSON.calculateObjectSize(simulatedNewDoc);
547+
const sizeDelta = newSize - oldSize;
563548

564-
// 4. Update the document
565-
result = await Model.findOneAndUpdate(
566-
queryFilter,
567-
{ $set: sanitizedData },
568-
{ new: true, runValidators: true, session },
569-
).lean();
570-
571-
// 5. Apply the delta (positive or negative) atomically
572-
await Project.findByIdAndUpdate(
573-
project._id,
574-
{ $inc: { databaseUsed: sizeDelta } },
575-
{ session }
576-
);
577-
578-
await session.commitTransaction();
579-
session.endSession();
580-
} catch (error) {
581-
await session.abortTransaction();
582-
session.endSession();
583-
throw error;
549+
// 3. Enforce quota if size is increasing
550+
if (sizeDelta > 0) {
551+
if ((project.databaseUsed || 0) + sizeDelta > project.databaseLimit) {
552+
return next(new AppError(403, "Storage quota exceeded. Please upgrade your plan."));
553+
}
584554
}
555+
556+
// 4. Update the document
557+
result = await Model.findOneAndUpdate(
558+
queryFilter,
559+
{ $set: sanitizedData },
560+
{ new: true, runValidators: true },
561+
).lean();
562+
563+
// 5. Apply the delta (positive or negative) atomically
564+
await Project.findByIdAndUpdate(
565+
project._id,
566+
{ $inc: { databaseUsed: sizeDelta } }
567+
);
585568
} else {
586569
// External DB Flow (No quota checks)
587570
result = await Model.findOneAndUpdate(

apps/web-dashboard/src/pages/Database.jsx

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -109,11 +109,18 @@ export default function Database() {
109109
if (f.field && f.value !== '') queryStr += `&${f.field}${f.operator === '=' ? '' : f.operator}=${encodeURIComponent(f.value)}`;
110110
});
111111
const res = await api.get(`/api/projects/${projectId}/collections/${activeCollection.name}/data${queryStr}`);
112-
// Handle wrapped metadata response
113-
if (res.data && res.data.items) {
112+
// Handle standard API response format { success, data: { items, total } }
113+
if (res.data?.success && res.data?.data?.items) {
114+
setData(res.data.data.items);
115+
setTotalRecords(res.data.data.total || 0);
116+
}
117+
// Handle legacy metadata response { items, total }
118+
else if (res.data && res.data.items) {
114119
setData(res.data.items);
115120
setTotalRecords(res.data.total || 0);
116-
} else {
121+
}
122+
// Fallback
123+
else {
117124
setData(res.data || []);
118125
setTotalRecords(Array.isArray(res.data) ? res.data.length : 0);
119126
}

sdks/urbackend-sdk/src/errors.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -71,7 +71,7 @@ export async function parseApiError(response: Response): Promise<UrBackendError>
7171
candidate = JSON.stringify(errData.error);
7272
}
7373

74-
if (candidate.trim().length > 0 && candidate !== '[]' && candidate !== 'null') {
74+
if (candidate && candidate.trim().length > 0 && candidate !== '[]' && candidate !== 'null') {
7575
message = candidate;
7676
} else if ('message' in errData) {
7777
message = typeof errData.message === 'string' ? errData.message : JSON.stringify(errData.message);

0 commit comments

Comments
 (0)