#include "error_dialog.h" #include #include #include #include #include QErrorMessage *ErrorDialog::getDialog(QWidget *parent, const QString &errorMsg) { // Initialize the error dialog QErrorMessage *dialog = new QErrorMessage(parent); // parent is needed for the correct location dialog->setAttribute(Qt::WA_DeleteOnClose); // delete the dialog when closed // Hide the "don't show again" checkbox #define ERROR_DIALOG_NEW_VERSION 0 #if (ERROR_DIALOG_NEW_VERSION == 1 && QT_VERSION >= QT_VERSION_CHECK(6, 3, 0)) // You need to set DontShowAgainVisible to true in Qt 6.3 errorDialog->setDontShowAgainVisible(false); #else QCheckBox *cb = dialog->findChild(); if (cb) { cb->setEnabled(false); cb->hide(); } #endif #undef ERROR_DIALOG_NEW_VERSION // Set the window title dialog->setWindowTitle(QObject::tr("Information messages")); // Set minimum width size dialog->setMinimumWidth(600); return dialog; } void ErrorDialog::displayError(QWidget *parent, const QString &errorMsg) { qDebug() << "Displaying error message:" << errorMsg; QErrorMessage *dialog = getDialog(parent, errorMsg); if (errorMsg.contains("constraint failed")) { QString detailedMessage = handleSqlConstraints(errorMsg); dialog->showMessage(detailedMessage); dialog->exec(); return; } if (errorMsg.contains("not found")) { QString detailedMessage = handleNotFoundErrors(errorMsg); dialog->showMessage(detailedMessage); dialog->exec(); return; } QRegularExpression regex("Error (\\d+):"); QRegularExpressionMatch match = regex.match(errorMsg); if (!match.hasMatch()) { dialog->showMessage(QObject::tr( "An error occurred from an unknown source of the problem.")); dialog->exec(); return; } int errorCode = match.captured(1).toInt(); QString detailedMessage = getDetailedMessage(errorCode); dialog->showMessage(detailedMessage); dialog->exec(); } QString ErrorDialog::handleNotFoundErrors(const QString &errorMsg) { if (errorMsg.contains("Genre", Qt::CaseInsensitive)) { return QObject::tr("The specified genre was not found."); } if (errorMsg.contains("Hall", Qt::CaseInsensitive)) { return QObject::tr("The specified hall was not found."); } if (errorMsg.contains("Movie", Qt::CaseInsensitive)) { return QObject::tr("The specified movie was not found."); } if (errorMsg.contains("Refund", Qt::CaseInsensitive)) { return QObject::tr("The specified refund was not found."); } if (errorMsg.contains("Session", Qt::CaseInsensitive)) { return QObject::tr("The specified session was not found."); } if (errorMsg.contains("Ticket", Qt::CaseInsensitive)) { return QObject::tr("The specified ticket was not found."); } // If the specific error is not recognized, return a general message return QObject::tr("The requested object was not found in the database."); } QString ErrorDialog::handleSqlConstraints(const QString &errorMsg) { if (errorMsg.contains("UNIQUE constraint failed")) { return handleUniqueConstraint(errorMsg); } if (errorMsg.contains("FOREIGN KEY constraint failed")) { return handleForeignKeyConstraint(errorMsg); } if (errorMsg.contains("PRIMARY KEY constraint failed")) { return handlePrimaryKeyConstraint(); } if (errorMsg.contains("CHECK constraint failed")) { return handleCheckConstraint(errorMsg); } if (errorMsg.contains("NOT NULL constraint failed")) { return tr("A required field is missing. Please fill all required fields."); } return tr("An SQL constraint violation occurred, but at the moment it has " "not been described in detail yet."); } QString ErrorDialog::handleUniqueConstraint(const QString &errorMsg) { if (errorMsg.contains("genres.genre_name")) { return tr("A genre with the same name already exists."); } if (errorMsg.contains("movies.title")) { return tr("A movie with the same title already exists."); } if (errorMsg.contains("halls.hall_name")) { return tr("A hall with the same name already exists."); } if (errorMsg.contains("tickets.session_id, tickets.seat_number")) { return tr("A ticket with the same session and seat number already exists."); } if (errorMsg.contains("refunds.ticket_id")) { return tr("A refund for the same ticket already exists."); } if (errorMsg.contains("sessions.hall_id, sessions.begin_at")) { return tr("A session is already scheduled in this hall at the same time."); } return tr("A unique constraint violation occurred, but at the moment it has " "not been described in detail yet."); } QString ErrorDialog::handleForeignKeyConstraint(const QString &errorMsg) { if (errorMsg.contains("sessions.movie_id")) { return tr("The movie ID for the session does not exist."); } if (errorMsg.contains("sessions.hall_id")) { return tr("The hall ID for the session does not exist."); } if (errorMsg.contains("movies.genre_id")) { return tr("The genre ID for the movie does not exist."); } if (errorMsg.contains("tickets.session_id")) { return tr("The session ID for the ticket does not exist."); } if (errorMsg.contains("refunds.ticket_id")) { return tr("The ticket ID for the refund does not exist."); } return tr("Operation violates a foreign key constraint, but at the moment it " "has not been described in detail yet."); } QString ErrorDialog::handlePrimaryKeyConstraint() { return tr("Duplicate primary key value. Ensure the primary key is unique."); } QString ErrorDialog::handleCheckConstraint(const QString &errorMsg) { if (errorMsg.contains("length(genre_name) > 0")) { return tr("Genre name must not be empty."); } if (errorMsg.contains("length(title) > 0")) { return tr("Movie title must not be empty."); } if (errorMsg.contains("duration > 0")) { return tr("Movie duration must be a positive value."); } if (errorMsg.contains("length(hall_name) > 0")) { return tr("Hall name must not be empty."); } if (errorMsg.contains("capacity > 0")) { return tr("Hall capacity must be a positive number."); } if (errorMsg.contains("ticket_price >= 0")) { return tr("Ticket price must be a non-negative value."); } if (errorMsg.contains("seat_number > 0")) { return tr("Seat number must be a positive value."); } if (errorMsg.contains("refund_amount >= 0")) { return tr("Refund amount must be a non-negative value."); } return tr("A value violates a CHECK constraint, but at the moment it has not " "been described in detail yet."); } QString ErrorDialog::getDetailedMessage(int errorCode) { switch (errorCode) { case 1001: return tr("Seat number exceeds hall capacity."); case 1002: return tr("Cannot purchase ticket after the session has started."); case 1003: return tr("Refunds cannot be made after the session has started."); case 1004: return tr("Refund amount cannot exceed the sale amount."); case 1005: return tr("Refund date cannot be earlier than the sale date."); case 1006: return tr("The new session overlaps with an ongoing movie in the hall."); default: return tr("A known error has occurred, but at the moment it has not been " "described in detail yet."); } }