mirror of
https://github.com/freedbygrace/DynamoDNS.git
synced 2026-07-26 11:38:13 +00:00
Fix DNS record creation errors by improving database interaction and error handling.
Replit-Commit-Author: Agent Replit-Commit-Session-Id: 9111ef36-26c8-4085-84ca-a35dc1fec1b5 Replit-Commit-Screenshot-Url: https://storage.googleapis.com/screenshot-production-us-central1/7083d608-d6d3-4a6a-9a27-6286c5109627/0f835696-98d6-415e-a356-3ae3f82c93f9.jpg
This commit is contained in:
+98
-53
@@ -470,61 +470,106 @@ export class DatabaseStorage implements IStorage {
|
||||
|
||||
async createDnsRecord(record: InsertDnsRecord): Promise<DnsRecord> {
|
||||
try {
|
||||
console.log("Creating DNS record with data:", record);
|
||||
console.log("Creating DNS record with data:", JSON.stringify(record, null, 2));
|
||||
|
||||
// Convert snake_case field names for database compatibility
|
||||
// We don't need providerId as it's not in the db table
|
||||
const { proxied, isAutoIP, providerId, ...validFields } = record as any;
|
||||
|
||||
// Create SQL query with proper parameterization using SQL template literals
|
||||
const queryText = sql`
|
||||
INSERT INTO dns_records (
|
||||
domain_id, name, type, content, ttl, priority,
|
||||
is_active, auto_update, notes, last_updated, provider_record_id
|
||||
) VALUES (
|
||||
${validFields.domainId},
|
||||
${validFields.name},
|
||||
${validFields.type},
|
||||
${validFields.content || ''},
|
||||
${validFields.ttl || 3600},
|
||||
${validFields.priority || 0},
|
||||
${validFields.isActive !== undefined ? validFields.isActive : true},
|
||||
${isAutoIP !== undefined ? isAutoIP : false},
|
||||
${validFields.notes || null},
|
||||
${new Date()},
|
||||
${validFields.providerRecordId || null}
|
||||
)
|
||||
RETURNING *
|
||||
`;
|
||||
|
||||
// Execute the query directly with SQL template literal
|
||||
const result = await db.execute(queryText);
|
||||
|
||||
if (!Array.isArray(result) || result.length === 0) {
|
||||
console.error("DNS record creation failed - empty result returned");
|
||||
throw new Error("Failed to create DNS record");
|
||||
}
|
||||
|
||||
const newRecord = result[0];
|
||||
console.log("New DNS record created:", newRecord);
|
||||
|
||||
// Return the record with frontend-expected field names
|
||||
return {
|
||||
id: newRecord.id,
|
||||
domainId: newRecord.domain_id,
|
||||
name: newRecord.name,
|
||||
type: newRecord.type,
|
||||
content: newRecord.content,
|
||||
ttl: newRecord.ttl,
|
||||
priority: newRecord.priority,
|
||||
isActive: newRecord.is_active,
|
||||
isAutoIP: newRecord.auto_update, // Map auto_update to isAutoIP
|
||||
notes: newRecord.notes,
|
||||
lastUpdated: newRecord.last_updated,
|
||||
createdAt: newRecord.created_at,
|
||||
providerRecordId: newRecord.provider_record_id,
|
||||
proxied: null // Maintained for frontend compatibility
|
||||
// Try a simpler approach using drizzle API directly
|
||||
// We need to map the properties to match the database column names
|
||||
const recordData = {
|
||||
domain_id: record.domainId,
|
||||
name: record.name,
|
||||
type: record.type,
|
||||
content: record.content || '',
|
||||
ttl: record.ttl || 3600,
|
||||
priority: record.priority || 0,
|
||||
is_active: record.isActive !== undefined ? record.isActive : true,
|
||||
auto_update: record.isAutoIP !== undefined ? record.isAutoIP : false,
|
||||
notes: record.notes || null,
|
||||
last_updated: new Date(),
|
||||
provider_record_id: record.providerRecordId || null
|
||||
};
|
||||
|
||||
console.log("Inserting DNS record with:", JSON.stringify(recordData, null, 2));
|
||||
|
||||
try {
|
||||
// Insert using the drizzle query builder
|
||||
const [newRecord] = await db.insert(dnsRecords)
|
||||
.values(recordData)
|
||||
.returning();
|
||||
|
||||
console.log("New DNS record created:", JSON.stringify(newRecord, null, 2));
|
||||
|
||||
// Convert from DB schema to application schema
|
||||
return {
|
||||
id: newRecord.id,
|
||||
domainId: newRecord.domainId,
|
||||
name: newRecord.name,
|
||||
type: newRecord.type,
|
||||
content: newRecord.content,
|
||||
ttl: newRecord.ttl,
|
||||
priority: newRecord.priority,
|
||||
isActive: newRecord.isActive,
|
||||
isAutoIP: newRecord.isAutoIP,
|
||||
notes: newRecord.notes,
|
||||
lastUpdated: newRecord.lastUpdated,
|
||||
createdAt: newRecord.createdAt,
|
||||
providerRecordId: newRecord.providerRecordId,
|
||||
proxied: null // For frontend compatibility
|
||||
};
|
||||
} catch (drizzleError) {
|
||||
console.error("Drizzle error creating DNS record:", drizzleError);
|
||||
|
||||
// Fallback to SQL approach if drizzle approach fails
|
||||
console.log("Falling back to SQL approach");
|
||||
|
||||
const queryText = sql`
|
||||
INSERT INTO dns_records (
|
||||
domain_id, name, type, content, ttl, priority,
|
||||
is_active, auto_update, notes, last_updated, provider_record_id
|
||||
) VALUES (
|
||||
${record.domainId},
|
||||
${record.name},
|
||||
${record.type},
|
||||
${record.content || ''},
|
||||
${record.ttl || 3600},
|
||||
${record.priority || 0},
|
||||
${record.isActive !== undefined ? record.isActive : true},
|
||||
${record.isAutoIP !== undefined ? record.isAutoIP : false},
|
||||
${record.notes || null},
|
||||
${new Date()},
|
||||
${record.providerRecordId || null}
|
||||
)
|
||||
RETURNING *
|
||||
`;
|
||||
|
||||
// Execute the query directly with SQL template literal
|
||||
const result = await db.execute(queryText);
|
||||
|
||||
if (!Array.isArray(result) || result.length === 0) {
|
||||
console.error("DNS record creation failed - empty result returned");
|
||||
throw new Error("Failed to create DNS record");
|
||||
}
|
||||
|
||||
const sqlRecord = result[0];
|
||||
console.log("New DNS record created with SQL:", sqlRecord);
|
||||
|
||||
// Map the SQL result to the expected DnsRecord type
|
||||
return {
|
||||
id: sqlRecord.id,
|
||||
domainId: sqlRecord.domain_id,
|
||||
name: sqlRecord.name,
|
||||
type: sqlRecord.type,
|
||||
content: sqlRecord.content,
|
||||
ttl: sqlRecord.ttl,
|
||||
priority: sqlRecord.priority,
|
||||
isActive: sqlRecord.is_active,
|
||||
isAutoIP: sqlRecord.auto_update,
|
||||
notes: sqlRecord.notes,
|
||||
lastUpdated: sqlRecord.last_updated,
|
||||
createdAt: sqlRecord.created_at,
|
||||
providerRecordId: sqlRecord.provider_record_id,
|
||||
proxied: null // For frontend compatibility
|
||||
};
|
||||
}
|
||||
} catch (error) {
|
||||
console.error("Error in createDnsRecord:", error);
|
||||
throw error;
|
||||
|
||||
+26
-4
@@ -108,7 +108,11 @@ export async function registerRoutes(app: Express): Promise<Server> {
|
||||
|
||||
app.post("/api/dns-records", requireRole(["admin", "manager"]), async (req, res) => {
|
||||
try {
|
||||
console.log("Creating DNS record with request body:", JSON.stringify(req.body));
|
||||
|
||||
// Validate the request data
|
||||
const validatedData = insertDnsRecordSchema.parse(req.body);
|
||||
console.log("Data after validation:", JSON.stringify(validatedData));
|
||||
|
||||
// Convert "none" to null for providerId if present
|
||||
if (validatedData.providerId === "none") {
|
||||
@@ -120,11 +124,22 @@ export async function registerRoutes(app: Express): Promise<Server> {
|
||||
const domain = await storage.getDomain(validatedData.domainId);
|
||||
if (domain) {
|
||||
validatedData.providerId = domain.providerId;
|
||||
console.log(`Setting providerId from domain: ${domain.providerId}`);
|
||||
} else {
|
||||
console.log(`Domain not found: ${validatedData.domainId}`);
|
||||
}
|
||||
}
|
||||
|
||||
// Make sure content is never undefined or null for non-AUTO records
|
||||
if (!validatedData.isAutoIP && (!validatedData.content || validatedData.content.trim() === '')) {
|
||||
validatedData.content = '';
|
||||
console.log("Setting empty content for non-AUTO record");
|
||||
}
|
||||
|
||||
try {
|
||||
console.log("Calling storage.createDnsRecord with:", JSON.stringify(validatedData));
|
||||
const record = await storage.createDnsRecord(validatedData);
|
||||
console.log("DNS record created successfully:", JSON.stringify(record));
|
||||
|
||||
// Track history
|
||||
await storage.addDnsHistory(
|
||||
@@ -140,15 +155,22 @@ export async function registerRoutes(app: Express): Promise<Server> {
|
||||
|
||||
res.status(201).json(record);
|
||||
} catch (error) {
|
||||
console.error("Error creating DNS record:", error);
|
||||
res.status(500).json({ message: "Internal server error" });
|
||||
console.error("Error creating DNS record in storage:", error);
|
||||
res.status(500).json({
|
||||
message: "Failed to create DNS record",
|
||||
error: error instanceof Error ? error.message : String(error)
|
||||
});
|
||||
}
|
||||
} catch (error) {
|
||||
if (error instanceof z.ZodError) {
|
||||
console.error("Validation error:", error.errors);
|
||||
res.status(400).json({ message: "Validation error", errors: error.errors });
|
||||
} else {
|
||||
console.error("Error creating DNS record:", error);
|
||||
res.status(500).json({ message: "Internal server error" });
|
||||
console.error("Unexpected error creating DNS record:", error);
|
||||
res.status(500).json({
|
||||
message: "Internal server error",
|
||||
error: error instanceof Error ? error.message : String(error)
|
||||
});
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user