218 lines
7.3 KiB
C++
218 lines
7.3 KiB
C++
#include "error_dialog.h"
|
|
|
|
#include <QCheckBox>
|
|
#include <QDebug>
|
|
#include <QErrorMessage>
|
|
#include <QRegularExpression>
|
|
#include <QRegularExpressionMatch>
|
|
|
|
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<QCheckBox *>();
|
|
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.");
|
|
}
|
|
}
|