IDEMPIERE-1207 Fixed inconsistent error message for well known database exception.

This commit is contained in:
Heng Sin Low 2013-07-29 17:14:52 +08:00
parent aaa4806797
commit d70244f8bc
10 changed files with 306 additions and 147 deletions

View File

@ -0,0 +1,13 @@
-- Jul 29, 2013 5:05:15 PM MYT
-- IDEMPIERE-1207 Fixed inconsistent error message for well known database exception
INSERT INTO AD_Message (MsgType,MsgText,AD_Message_ID,EntityType,AD_Message_UU,Value,IsActive,Updated,CreatedBy,UpdatedBy,AD_Org_ID,Created,AD_Client_ID) VALUES ('E','The database operation timed out. Please try again later.',200217,'D','bfc4529a-0ec2-4e8b-92d4-f86ca829cd4d','DatabaseOperationTimeout','Y',TO_DATE('2013-07-29 17:05:02','YYYY-MM-DD HH24:MI:SS'),100,100,0,TO_DATE('2013-07-29 17:05:02','YYYY-MM-DD HH24:MI:SS'),0)
;
-- Jul 29, 2013 5:05:15 PM MYT
-- IDEMPIERE-1207 Fixed inconsistent error message for well known database exception
INSERT INTO AD_Message_Trl (AD_Language,AD_Message_ID, MsgText,MsgTip, IsTranslated,AD_Client_ID,AD_Org_ID,Created,Createdby,Updated,UpdatedBy,AD_Message_Trl_UU ) SELECT l.AD_Language,t.AD_Message_ID, t.MsgText,t.MsgTip, 'N',t.AD_Client_ID,t.AD_Org_ID,t.Created,t.Createdby,t.Updated,t.UpdatedBy,Generate_UUID() FROM AD_Language l, AD_Message t WHERE l.IsActive='Y' AND l.IsSystemLanguage='Y' AND l.IsBaseLanguage='N' AND t.AD_Message_ID=200217 AND NOT EXISTS (SELECT * FROM AD_Message_Trl tt WHERE tt.AD_Language=l.AD_Language AND tt.AD_Message_ID=t.AD_Message_ID)
;
SELECT register_migration_script('201307290906_IDEMPIERE-1207.sql') FROM dual
;

View File

@ -0,0 +1,13 @@
-- Jul 29, 2013 5:05:15 PM MYT
-- IDEMPIERE-1207 Fixed inconsistent error message for well known database exception
INSERT INTO AD_Message (MsgType,MsgText,AD_Message_ID,EntityType,AD_Message_UU,Value,IsActive,Updated,CreatedBy,UpdatedBy,AD_Org_ID,Created,AD_Client_ID) VALUES ('E','The database operation timed out. Please try again later.',200217,'D','bfc4529a-0ec2-4e8b-92d4-f86ca829cd4d','DatabaseOperationTimeout','Y',TO_TIMESTAMP('2013-07-29 17:05:02','YYYY-MM-DD HH24:MI:SS'),100,100,0,TO_TIMESTAMP('2013-07-29 17:05:02','YYYY-MM-DD HH24:MI:SS'),0)
;
-- Jul 29, 2013 5:05:15 PM MYT
-- IDEMPIERE-1207 Fixed inconsistent error message for well known database exception
INSERT INTO AD_Message_Trl (AD_Language,AD_Message_ID, MsgText,MsgTip, IsTranslated,AD_Client_ID,AD_Org_ID,Created,Createdby,Updated,UpdatedBy,AD_Message_Trl_UU ) SELECT l.AD_Language,t.AD_Message_ID, t.MsgText,t.MsgTip, 'N',t.AD_Client_ID,t.AD_Org_ID,t.Created,t.Createdby,t.Updated,t.UpdatedBy,Generate_UUID() FROM AD_Language l, AD_Message t WHERE l.IsActive='Y' AND l.IsSystemLanguage='Y' AND l.IsBaseLanguage='N' AND t.AD_Message_ID=200217 AND NOT EXISTS (SELECT * FROM AD_Message_Trl tt WHERE tt.AD_Language=l.AD_Language AND tt.AD_Message_ID=t.AD_Message_ID)
;
SELECT register_migration_script('201307290906_IDEMPIERE-1207.sql') FROM dual
;

View File

@ -36,6 +36,9 @@ import org.compiere.util.DB;
*/ */
public class DBException extends AdempiereException public class DBException extends AdempiereException
{ {
public static final String DATABASE_OPERATION_TIMEOUT_MSG = "DatabaseOperationTimeout";
public static final String DELETE_ERROR_DEPENDENT_MSG = "DeleteErrorDependent";
public static final String SAVE_ERROR_NOT_UNIQUE_MSG = "SaveErrorNotUnique";
/** /**
* *
*/ */
@ -198,4 +201,19 @@ public class DBException extends AdempiereException
return isSQLState(e, "57014"); return isSQLState(e, "57014");
return isErrorCode(e, 1013); return isErrorCode(e, 1013);
} }
/**
* @param e
*/
public static String getDefaultDBExceptionMessage(Exception e) {
if (isUniqueContraintError(e)) {
return SAVE_ERROR_NOT_UNIQUE_MSG;
} else if (isChildRecordFoundError(e)) {
return DELETE_ERROR_DEPENDENT_MSG;
} else if (isTimeout(e)) {
return DATABASE_OPERATION_TIMEOUT_MSG;
} else {
return null;
}
}
} // DBException } // DBException

View File

@ -60,6 +60,7 @@ import org.compiere.util.MSort;
import org.compiere.util.Msg; import org.compiere.util.Msg;
import org.compiere.util.SecureEngine; import org.compiere.util.SecureEngine;
import org.compiere.util.Trx; import org.compiere.util.Trx;
import org.compiere.util.Util;
import org.compiere.util.ValueNamePair; import org.compiere.util.ValueNamePair;
/** /**
@ -2029,10 +2030,11 @@ public class GridTable extends AbstractTableModel
{ {
String msg = "SaveError"; String msg = "SaveError";
if (DBException.isUniqueContraintError(e)) // Unique Constraint String dbException = DBException.getDefaultDBExceptionMessage(e);
if (!Util.isEmpty(dbException))
{ {
log.log(Level.SEVERE, "Key Not Unique", e); log.log(Level.SEVERE, dbException, e);
msg = "SaveErrorNotUnique"; msg = dbException;
} }
else else
log.log(Level.SEVERE, select.toString(), e); log.log(Level.SEVERE, select.toString(), e);
@ -2175,9 +2177,6 @@ public class GridTable extends AbstractTableModel
info = ppE.getName(); info = ppE.getName();
if ("DBExecuteError".equals(msg)) if ("DBExecuteError".equals(msg))
info = "DBExecuteError:" + info; info = "DBExecuteError:" + info;
// Unique Constraint
if (DBException.isUniqueContraintError(CLogger.retrieveException()))
msg = "SaveErrorNotUnique";
} }
fireDataStatusEEvent(msg, info, true); fireDataStatusEEvent(msg, info, true);
return SAVE_ERROR; return SAVE_ERROR;
@ -2668,8 +2667,9 @@ public class GridTable extends AbstractTableModel
{ {
log.log(Level.SEVERE, sql.toString(), e); log.log(Level.SEVERE, sql.toString(), e);
String msg = "DeleteError"; String msg = "DeleteError";
if (DBException.isChildRecordFoundError(e)) String dbMsg = DBException.getDefaultDBExceptionMessage(e);
msg = "DeleteErrorDependent"; if (!Util.isEmpty(dbMsg))
msg = dbMsg;
fireDataStatusEEvent(msg, e.getLocalizedMessage(), true); fireDataStatusEEvent(msg, e.getLocalizedMessage(), true);
return false; return false;
} }

View File

@ -28,6 +28,7 @@ import java.util.Locale;
import java.util.Properties; import java.util.Properties;
import java.util.logging.Level; import java.util.logging.Level;
import org.adempiere.exceptions.DBException;
import org.compiere.util.CCache; import org.compiere.util.CCache;
import org.compiere.util.CLogger; import org.compiere.util.CLogger;
import org.compiere.util.DB; import org.compiere.util.DB;
@ -276,7 +277,7 @@ public class MColumn extends X_AD_Column
new Object[] {getAD_Table_ID(), getAD_Column_ID(), getSeqNo()}); new Object[] {getAD_Table_ID(), getAD_Column_ID(), getSeqNo()});
if (cnt>0) if (cnt>0)
{ {
log.saveError("SaveErrorNotUnique", Msg.getElement(getCtx(), COLUMNNAME_SeqNo)); log.saveError(DBException.SAVE_ERROR_NOT_UNIQUE_MSG, Msg.getElement(getCtx(), COLUMNNAME_SeqNo));
return false; return false;
} }
} }

View File

@ -33,6 +33,7 @@ import java.util.logging.Level;
import javax.mail.internet.AddressException; import javax.mail.internet.AddressException;
import javax.mail.internet.InternetAddress; import javax.mail.internet.InternetAddress;
import org.adempiere.exceptions.DBException;
import org.compiere.util.CCache; import org.compiere.util.CCache;
import org.compiere.util.CLogger; import org.compiere.util.CLogger;
import org.compiere.util.DB; import org.compiere.util.DB;
@ -910,7 +911,7 @@ public class MUser extends X_AD_User
"SELECT COUNT(*) FROM AD_User WHERE Password IS NOT NULL AND EMail=? AND AD_Client_ID=? AND AD_User_ID!=?", "SELECT COUNT(*) FROM AD_User WHERE Password IS NOT NULL AND EMail=? AND AD_Client_ID=? AND AD_User_ID!=?",
getEMail(), getAD_Client_ID(), getAD_User_ID()); getEMail(), getAD_Client_ID(), getAD_User_ID());
if (cnt > 0) { if (cnt > 0) {
log.saveError("SaveError", Msg.getMsg(getCtx(), "SaveErrorNotUnique", true) + Msg.getElement(getCtx(), COLUMNNAME_EMail)); log.saveError("SaveError", Msg.getMsg(getCtx(), DBException.SAVE_ERROR_NOT_UNIQUE_MSG, true) + Msg.getElement(getCtx(), COLUMNNAME_EMail));
return false; return false;
} }
} }

View File

@ -20,6 +20,7 @@ import java.sql.ResultSet;
import java.util.Properties; import java.util.Properties;
import java.util.logging.Level; import java.util.logging.Level;
import org.adempiere.exceptions.DBException;
import org.compiere.util.DB; import org.compiere.util.DB;
import org.compiere.util.Env; import org.compiere.util.Env;
import org.compiere.util.Msg; import org.compiere.util.Msg;
@ -192,7 +193,7 @@ public class M_Element extends X_AD_Element
sql.append(" AND AD_Element_ID<>").append(get_ID()); sql.append(" AND AD_Element_ID<>").append(get_ID());
int no = DB.getSQLValue(null, sql.toString(), columnName.toUpperCase()); int no = DB.getSQLValue(null, sql.toString(), columnName.toUpperCase());
if (no > 0) { if (no > 0) {
log.saveError("SaveErrorNotUnique", Msg.getElement(getCtx(), COLUMNNAME_ColumnName)); log.saveError(DBException.SAVE_ERROR_NOT_UNIQUE_MSG, Msg.getElement(getCtx(), COLUMNNAME_ColumnName));
return false; return false;
} }
} }

View File

@ -1963,7 +1963,6 @@ public abstract class PO
* To reload call load() - not updated * To reload call load() - not updated
* @return true if saved * @return true if saved
*/ */
@SuppressWarnings("unused")
public boolean save() public boolean save()
{ {
CLogger.resetLast(); CLogger.resetLast();
@ -2061,7 +2060,8 @@ public abstract class PO
catch (Exception e) catch (Exception e)
{ {
log.log(Level.WARNING, "beforeSave - " + toString(), e); log.log(Level.WARNING, "beforeSave - " + toString(), e);
log.saveError("Error", e, false); String msg = DBException.getDefaultDBExceptionMessage(e);
log.saveError(msg != null ? msg : "Error", e, false);
if (localTrx != null) if (localTrx != null)
{ {
localTrx.rollback(); localTrx.rollback();
@ -2139,9 +2139,11 @@ public abstract class PO
} }
} }
} }
catch (SQLException e) catch (Exception e)
{ {
log.log(Level.WARNING, "afterSave - " + toString(), e); log.log(Level.WARNING, "afterSave - " + toString(), e);
String msg = DBException.getDefaultDBExceptionMessage(e);
log.saveError(msg != null ? msg : "Error", e);
if (localTrx != null) if (localTrx != null)
{ {
localTrx.rollback(); localTrx.rollback();
@ -3110,6 +3112,8 @@ public abstract class PO
} }
Trx localTrx = null; Trx localTrx = null;
Trx trx = null;
Savepoint savepoint = null;
boolean success = false; boolean success = false;
try try
{ {
@ -3121,20 +3125,58 @@ public abstract class PO
localTrx = Trx.get(localTrxName, true); localTrx = Trx.get(localTrxName, true);
m_trxName = localTrxName; m_trxName = localTrxName;
} }
else
{
trx = Trx.get(m_trxName, false);
if (trx == null)
{
// Using a trx that was previously closed or never opened
// Creating and starting the transaction right here, but please note
// that this is not a good practice
trx = Trx.get(m_trxName, true);
log.severe("Transaction closed or never opened ("+m_trxName+") => starting now --> " + toString());
}
}
try try
{ {
// If not a localTrx we need to set a savepoint for rollback
if (localTrx == null)
savepoint = trx.setSavepoint(null);
if (!beforeDelete()) if (!beforeDelete())
{ {
log.warning("beforeDelete failed"); log.warning("beforeDelete failed");
if (localTrx != null)
{
localTrx.rollback();
}
else if (savepoint != null)
{
try {
trx.rollback(savepoint);
} catch (SQLException e) {}
savepoint = null;
}
return false; return false;
} }
} }
catch (Exception e) catch (Exception e)
{ {
log.log(Level.WARNING, "beforeDelete", e); log.log(Level.WARNING, "beforeDelete", e);
log.saveError("Error", e, false); String msg = DBException.getDefaultDBExceptionMessage(e);
// throw new DBException(e); log.saveError(msg != null ? msg : "Error", e, false);
if (localTrx != null)
{
localTrx.rollback();
}
else if (savepoint != null)
{
try {
trx.rollback(savepoint);
} catch (SQLException e1) {}
savepoint = null;
}
return false; return false;
} }
// Delete Restrict AD_Table_ID/Record_ID (Requests, ..) // Delete Restrict AD_Table_ID/Record_ID (Requests, ..)
@ -3142,6 +3184,17 @@ public abstract class PO
if (errorMsg != null) if (errorMsg != null)
{ {
log.saveError("CannotDelete", errorMsg); log.saveError("CannotDelete", errorMsg);
if (localTrx != null)
{
localTrx.rollback();
}
else if (savepoint != null)
{
try {
trx.rollback(savepoint);
} catch (SQLException e) {}
savepoint = null;
}
return false; return false;
} }
// Call ModelValidators TYPE_DELETE // Call ModelValidators TYPE_DELETE
@ -3151,9 +3204,22 @@ public abstract class PO
if (errorMsg != null) if (errorMsg != null)
{ {
log.saveError("Error", errorMsg); log.saveError("Error", errorMsg);
if (localTrx != null)
{
localTrx.rollback();
}
else if (savepoint != null)
{
try {
trx.rollback(savepoint);
} catch (SQLException e) {}
savepoint = null;
}
return false; return false;
} }
try
{
// //
deleteTranslations(localTrxName); deleteTranslations(localTrxName);
// Delete Cascade AD_Table_ID/Record_ID (Attachments, ..) // Delete Cascade AD_Table_ID/Record_ID (Attachments, ..)
@ -3170,6 +3236,13 @@ public abstract class PO
else else
no = DB.executeUpdate(sql.toString(), localTrxName); no = DB.executeUpdate(sql.toString(), localTrxName);
success = no == 1; success = no == 1;
}
catch (Exception e)
{
String msg = DBException.getDefaultDBExceptionMessage(e);
log.saveError(msg != null ? msg : e.getLocalizedMessage(), e);
success = false;
}
// Save ID // Save ID
m_idOld = get_ID(); m_idOld = get_ID();
@ -3178,8 +3251,17 @@ public abstract class PO
{ {
log.warning("Not deleted"); log.warning("Not deleted");
if (localTrx != null) if (localTrx != null)
{
localTrx.rollback(); localTrx.rollback();
} }
else if (savepoint != null)
{
try {
trx.rollback(savepoint);
} catch (SQLException e) {}
savepoint = null;
}
}
else else
{ {
if (success) if (success)
@ -3237,7 +3319,8 @@ public abstract class PO
catch (Exception e) catch (Exception e)
{ {
log.log(Level.WARNING, "afterDelete", e); log.log(Level.WARNING, "afterDelete", e);
log.saveError("Error", e, false); String msg = DBException.getDefaultDBExceptionMessage(e);
log.saveError(msg != null ? msg : "Error", e, false);
success = false; success = false;
// throw new DBException(e); // throw new DBException(e);
} }
@ -3254,8 +3337,17 @@ public abstract class PO
if (!success) if (!success)
{ {
if (localTrx != null) if (localTrx != null)
{
localTrx.rollback(); localTrx.rollback();
} }
else if (savepoint != null)
{
try {
trx.rollback(savepoint);
} catch (SQLException e) {}
savepoint = null;
}
}
else else
{ {
if (localTrx != null) if (localTrx != null)
@ -3263,7 +3355,8 @@ public abstract class PO
try { try {
localTrx.commit(true); localTrx.commit(true);
} catch (SQLException e) { } catch (SQLException e) {
log.saveError("Error", e); String msg = DBException.getDefaultDBExceptionMessage(e);
log.saveError(msg != null ? msg : "Error", e);
success = false; success = false;
} }
} }
@ -3290,8 +3383,20 @@ public abstract class PO
localTrx.close(); localTrx.close();
m_trxName = null; m_trxName = null;
} }
else
{
if (savepoint != null)
{
try {
trx.releaseSavepoint(savepoint);
} catch (SQLException e) {
e.printStackTrace();
}
}
savepoint = null;
trx = null;
}
} }
// log.info("" + success);
return success; return success;
} // delete } // delete

View File

@ -1040,7 +1040,8 @@ public final class DB
else else
{ {
log.log(Level.SEVERE, cs.getSql() + " [" + trxName + "]", e); log.log(Level.SEVERE, cs.getSql() + " [" + trxName + "]", e);
log.saveError ("DBExecuteError", e); String msg = DBException.getDefaultDBExceptionMessage(e);
log.saveError (msg != null ? msg : "DBExecuteError", e);
} }
// throw new DBException(e); // throw new DBException(e);
} }

View File

@ -30,6 +30,7 @@ import java.util.concurrent.TimeUnit;
import java.util.logging.Level; import java.util.logging.Level;
import org.adempiere.exceptions.AdempiereException; import org.adempiere.exceptions.AdempiereException;
import org.adempiere.exceptions.DBException;
import org.compiere.Adempiere; import org.compiere.Adempiere;
import org.compiere.model.PO; import org.compiere.model.PO;
@ -369,6 +370,11 @@ public class Trx
fireAfterCommitEvent(false); fireAfterCommitEvent(false);
throw e; throw e;
} }
else
{
String msg = DBException.getDefaultDBExceptionMessage(e);
log.saveError(msg != null ? msg : e.getLocalizedMessage(), e);
}
} }
m_active = false; m_active = false;
fireAfterCommitEvent(false); fireAfterCommitEvent(false);