Skip to content
82 changes: 82 additions & 0 deletions fe/fe-core/src/main/java/com/starrocks/common/util/LogUtil.java
Original file line number Diff line number Diff line change
Expand Up @@ -27,9 +27,12 @@
import com.starrocks.service.FrontendOptions;

import java.lang.management.ThreadInfo;
import java.lang.reflect.InvocationTargetException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;

public class LogUtil {
Expand Down Expand Up @@ -197,4 +200,83 @@ private static void appendChar(StringBuilder sb, char character) {
sb.append(" ");
}
}

public static List<Throwable> unwindException(Throwable e, int maxDepth) {
List<Throwable> result = new ArrayList<>();
for (int i = 0; i < maxDepth; i++) {
if (e == null) {
break;
}
boolean skip = true;
Throwable parent = null;
if (e instanceof InvocationTargetException) {
parent = ((InvocationTargetException) e).getTargetException();
} else {
parent = e.getCause();
// A layer contributes nothing beyond its cause when either:
// - it has no message of its own (e.g. `new Foo(null, cause)`), or
// - its message is just the JDK default `Throwable(Throwable cause)` ctor's
// `cause.toString()` (e.g. ErrorReport.wrapWithRuntimeException's bare
// `new RuntimeException(ddlException)`, used purely to smuggle a checked
// exception past a signature that can't declare one).
// Unpeel such layers instead of showing the same text twice.
skip = parent != null && (e.getMessage() == null || Objects.equals(e.getMessage(), parent.toString()));
}
if (!skip) {
result.add(e);
}
if (parent == e) {
break;
}
e = parent;
}
return result;
}

public static String getUnwoundExceptionMessage(Throwable e) {
final int maxDepth = 20;
List<Throwable> unwound = unwindException(e, maxDepth);
// Some call sites re-wrap an exception into a different type purely for classification
// purposes (e.g. `new AnalysisException(semanticException.getMessage(), semanticException)`),
// carrying the same message forward unchanged. Collapse those adjacent duplicates so they
// don't show up twice, and so a message that was never really "unwound" doesn't get a
// class-name prefix it never had before.
List<Throwable> result = new ArrayList<>();
String prevMsg = null;
for (Throwable t : unwound) {
String msg = t.getMessage();
if (result.isEmpty() || !Objects.equals(msg, prevMsg)) {
result.add(t);
}
prevMsg = msg;
}
if (result.isEmpty()) {
return e.getMessage();
}
if (result.size() == 1) {
// e itself may have been unpeeled away as a content-free wrapper; report the surviving
// layer's own message rather than the original (possibly now-irrelevant) top-level message.
return result.get(0).getMessage();
}
// The outermost layer is usually a generic internal wrapper (e.g. StarRocksConnectorException,
// AnalysisException) whose class name carries no value to the user; only deeper layers reveal
// which underlying system actually failed, so only those get a class-name prefix.
StringBuilder sb = new StringBuilder();
for (int i = 0; i < result.size(); i++) {
Throwable t = result.get(i);
String msg = t.getMessage();
if (i > 0) {
sb.append(t.getClass().getSimpleName());
if (msg != null && !msg.isEmpty()) {
sb.append(": ");
}
}
if (msg != null) {
sb.append(msg);
}
sb.append("\n");
}
sb.deleteCharAt(sb.length() - 1);
return sb.toString();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -166,7 +166,7 @@ public void refreshTable(String dbName, String tblName, boolean onlyCachedPartit
((InvocationTargetException) cause).getTargetException() instanceof NoSuchObjectException) {
LOG.error("Failed to refresh table {}.{}: table does not exist", dbName, tblName, e);
invalidateTable(dbName, tblName);
throw new StarRocksConnectorException(e.getMessage() + ", invalidated cache.");
throw new StarRocksConnectorException(e.getMessage() + ", invalidated cache.", e);
} else {
LOG.error("Failed to refresh table {}.{}", dbName, tblName, e);
throw e;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,6 @@
import com.starrocks.connector.statistics.StatisticsUtils;
import com.starrocks.credential.CloudConfiguration;
import com.starrocks.qe.ConnectContext;
import com.starrocks.sql.analyzer.SemanticException;
import com.starrocks.sql.optimizer.OptimizerContext;
import com.starrocks.sql.optimizer.Utils;
import com.starrocks.sql.optimizer.operator.scalar.ColumnRefOperator;
Expand All @@ -56,7 +55,6 @@
import io.delta.kernel.internal.actions.Metadata;
import io.delta.kernel.types.StructType;
import io.delta.kernel.utils.CloseableIterator;
import org.apache.commons.lang.exception.ExceptionUtils;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;

Expand Down Expand Up @@ -384,15 +382,8 @@ public Table getTable(ConnectContext context, String dbName, String tblName) {
return deltaOps.getTable(dbName, tblName);
} catch (Exception e) {
LOG.error("Failed to get deltalake table {}.{}.{}", catalogName, dbName, tblName, e);
String errMsg = e.getMessage();
Throwable ce = ExceptionUtils.getRootCause(e);
if (ce instanceof SemanticException se) {
errMsg = se.getDetailMsg();
} else if (ce != null) {
errMsg = String.format("Failed to get deltalake table %s.%s.%s. %s", catalogName, dbName, tblName,
ce.getMessage());
}
throw new StarRocksConnectorException(errMsg, e);
throw new StarRocksConnectorException(
String.format("Failed to get Delta Lake table %s.%s.%s", catalogName, dbName, tblName), e);
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,6 @@
import com.starrocks.connector.metastore.IMetastore;
import com.starrocks.connector.metastore.MetastoreTable;
import com.starrocks.memory.estimate.Estimator;
import com.starrocks.sql.analyzer.SemanticException;
import io.delta.kernel.Scan;
import io.delta.kernel.ScanBuilder;
import io.delta.kernel.Table;
Expand Down Expand Up @@ -146,15 +145,13 @@ public DeltaLakeSnapshot getLatestSnapshot(String dbName, String tableName) {
Table deltaTable = Table.forPath(deltaLakeEngine, path);
snapshot = (SnapshotImpl) deltaTable.getLatestSnapshot(deltaLakeEngine);
} catch (TableNotFoundException e) {
LOG.error("Failed to find Delta table for {}.{}.{}, {}. caused by : {}", catalogName, dbName, tableName,
e.getMessage(), e.getCause());
throw new SemanticException("Failed to find Delta table for %s.%s.%s, %s. caused by : %s", catalogName,
dbName, tableName, e.getMessage(), e.getCause());
LOG.error("Failed to find Delta table for {}.{}.{}", catalogName, dbName, tableName, e);
throw new StarRocksConnectorException(
String.format("Failed to find Delta table %s.%s.%s", catalogName, dbName, tableName), e);
} catch (Exception e) {
LOG.error("Failed to get latest snapshot for {}.{}.{}, {}. caused by : {}", catalogName, dbName,
tableName, e.getMessage(), e.getCause());
throw new SemanticException("Failed to get latest snapshot for %s.%s.%s, %s. caused by : %s",
catalogName, dbName, tableName, e.getMessage(), e.getCause());
LOG.error("Failed to get latest snapshot for {}.{}.{}", catalogName, dbName, tableName, e);
throw new StarRocksConnectorException(
String.format("Failed to get latest snapshot for %s.%s.%s", catalogName, dbName, tableName), e);
}
return new DeltaLakeSnapshot(dbName, tableName, deltaLakeEngine, snapshot, metastoreTable);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,19 +29,4 @@ public StarRocksConnectorException(String message, Throwable cause) {
super(message, cause);
}

public String getErrorMessage() {
return super.getMessage();
}

@Override
public String getMessage() {
return getErrorMessage();
}

public static void check(boolean test, String message, Object... args) {
if (!test) {
throw new StarRocksConnectorException(message, args);
}
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -527,7 +527,7 @@ public boolean refreshView(String hiveDbName, String hiveViewName) {
if (cause instanceof InvocationTargetException &&
((InvocationTargetException) cause).getTargetException() instanceof NoSuchObjectException) {
invalidateTable(hiveDbName, hiveViewName);
throw new StarRocksConnectorException(e.getMessage() + ", invalidated cache.");
throw new StarRocksConnectorException(e.getMessage() + ", invalidated cache.", e);
} else {
throw e;
}
Expand All @@ -550,7 +550,7 @@ public List<HivePartitionName> refreshTableWithoutSync(String hiveDbName, String
if (cause instanceof InvocationTargetException &&
((InvocationTargetException) cause).getTargetException() instanceof NoSuchObjectException) {
invalidateTable(hiveDbName, hiveTblName);
throw new StarRocksConnectorException(e.getMessage() + ", invalidated cache.");
throw new StarRocksConnectorException(e.getMessage() + ", invalidated cache.", e);
} else {
throw e;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,6 @@
import com.starrocks.connector.exception.StarRocksConnectorException;
import com.starrocks.connector.hive.events.MetastoreNotificationFetchException;
import com.starrocks.connector.hive.glue.AWSCatalogMetastoreClient;
import org.apache.commons.lang.exception.ExceptionUtils;
import org.apache.hadoop.hive.conf.HiveConf;
import org.apache.hadoop.hive.metastore.HiveMetaHookLoader;
import org.apache.hadoop.hive.metastore.HiveMetaStoreClient;
Expand Down Expand Up @@ -171,8 +170,7 @@ public <T> T callRPC(String methodName, String messageIfError, Class<?>[] argCla
return (T) method.invoke(client.hiveClient, args);
} catch (Throwable e) {
LOG.error(messageIfError, e);
connectionException = new StarRocksConnectorException(messageIfError + ", msg: " +
ExceptionUtils.getRootCauseMessage(e), e);
connectionException = new StarRocksConnectorException(messageIfError, e);
Comment thread
dirtysalt marked this conversation as resolved.
throw connectionException;
} finally {
if (client == null && connectionException != null) {
Expand Down Expand Up @@ -460,7 +458,7 @@ private Map<String, List<ColumnStatisticsObj>> getPartitionColumnStatsWithRetry(
partitionStats.putAll(client.hiveClient.getPartitionColumnStatistics(dbName, tableName, parts, columnNames));
}
LOG.info("Succeed to getPartitionColumnStatistics on [{}.{}] with {} times retry, slice size is {}," +
" partName size is {}", dbName, tableName, retryNum, subListSize, partNames.size());
" partName size is {}", dbName, tableName, retryNum, subListSize, partNames.size());
return partitionStats;
} catch (TTransportException te) {
if (subListNum > 1) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@

public class HiveUtils {
private static final Logger LOG = LogManager.getLogger(HiveUtils.class);

public static boolean isS3Url(String prefix) {
return prefix.startsWith("oss://") || prefix.startsWith("s3n://") || prefix.startsWith("s3a://") ||
prefix.startsWith("s3://") || prefix.startsWith("cos://") || prefix.startsWith("cosn://") ||
Expand Down Expand Up @@ -174,10 +175,10 @@ public static LiteralExpr normalizeKey(LiteralExpr key, Type targetType) {
DecimalLiteral decimalKey = (DecimalLiteral) key;
ScalarType type = (ScalarType) targetType;
int scale = type.decimalScale();

BigDecimal scaled = decimalKey.getValue()
.setScale(scale, RoundingMode.HALF_UP);

key = new DecimalLiteral(scaled);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,6 @@
import com.starrocks.sql.optimizer.operator.scalar.ScalarOperator;
import com.starrocks.sql.optimizer.statistics.ColumnStatistic;
import com.starrocks.sql.optimizer.statistics.Statistics;
import org.apache.commons.lang.exception.ExceptionUtils;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;

Expand Down Expand Up @@ -132,10 +131,8 @@ public Table getTable(ConnectContext context, String dbName, String tblName) {
table = hmsOps.getTable(dbName, tblName);
} catch (Exception e) {
LOG.error("Failed to get hudi table [{}.{}.{}]", catalogName, dbName, tblName, e);
Throwable ce = ExceptionUtils.getRootCause(e);
String errMsg = ce != null ? ce.getMessage() : e.getMessage();
throw new StarRocksConnectorException(String.format("Failed to get hudi table %s.%s.%s. %s",
catalogName, dbName, tblName, errMsg), e);
throw new StarRocksConnectorException(
String.format("Failed to get hudi table %s.%s.%s", catalogName, dbName, tblName), e);
}

return table;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,6 @@
import com.starrocks.mysql.MysqlCommand;
import com.starrocks.qe.ConnectContext;
import com.starrocks.qe.SessionVariable;
import org.apache.commons.lang.exception.ExceptionUtils;
import org.apache.iceberg.BaseTable;
import org.apache.iceberg.ContentFile;
import org.apache.iceberg.DataFile;
Expand Down Expand Up @@ -286,10 +285,8 @@ public Table getTable(ConnectContext connectContext, String dbName, String table
} catch (NoSuchTableException e) {
throw e;
} catch (Exception e) {
Throwable ce = ExceptionUtils.getRootCause(e);
String errMsg = ce != null ? ce.getMessage() : e.getMessage();
throw new StarRocksConnectorException(String.format("Failed to get iceberg table %s.%s.%s. %s",
catalogName, dbName, tableName, errMsg), e);
throw new StarRocksConnectorException(
String.format("Failed to get iceberg table %s.%s.%s", catalogName, dbName, tableName), e);
} finally {
TABLE_LOAD_CONTEXT.remove();
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -485,7 +485,8 @@ public void truncateTable(TruncateTableStmt truncateTableStmt, ConnectContext co
deleteFiles.commit();
} catch (UncheckedIOException | ValidationException | CommitFailedException | CommitStateUnknownException e) {
LOG.error("Failed to truncate iceberg table: {}.{}", dbName, tableName, e);
throw new StarRocksConnectorException("Failed to truncate iceberg table: %s.%s", dbName, tableName, e);
throw new StarRocksConnectorException(
String.format("Failed to truncate iceberg table: %s.%s", dbName, tableName), e);
}
}

Expand Down Expand Up @@ -625,8 +626,8 @@ public void executeMetadataDelete(Table table, ScalarOperator predicate, Connect
} catch (UncheckedIOException | ValidationException | CommitFailedException | CommitStateUnknownException e) {
LOG.error("Failed to execute metadata delete on {}.{}", dbName, tableName, e);
ConnectorMetricsMgr.increaseDeleteTotalFail(ConnectorMetricsMgr.CONNECTOR_ICEBERG, e, deleteType);
throw new StarRocksConnectorException("Failed to execute metadata delete on %s.%s: %s",
dbName, tableName, e.getMessage());
throw new StarRocksConnectorException(
String.format("Failed to execute metadata delete on %s.%s", dbName, tableName), e);
} finally {
ConnectorMetricsMgr.increaseDeleteDurationMs(ConnectorMetricsMgr.CONNECTOR_ICEBERG,
System.currentTimeMillis() - startMs, deleteType);
Expand Down Expand Up @@ -1115,7 +1116,7 @@ public List<PartitionKey> getPrunedPartitions(Table table, ScalarOperator predic
partitionKeys.add(createPartitionKeyWithType(values, srTypes, table.getType()));
} catch (Exception e) {
LOG.error("create partition key failed.", e);
throw new StarRocksConnectorException(e.getMessage());
throw new StarRocksConnectorException("create partition key failed", e);
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -104,7 +104,8 @@ public void createDB(ConnectContext context, String dbName, Map<String, String>
fileSystem.exists(new Path(value));
} catch (Exception e) {
LOG.error("Invalid location URI: {}", value, e);
throw new StarRocksConnectorException("Invalid location URI: %s. msg: %s", value, e.getMessage());
throw new StarRocksConnectorException(
String.format("Invalid location URI: %s", value), e);
}
} else {
throw new IllegalArgumentException("Unrecognized property: " + key);
Expand All @@ -121,7 +122,7 @@ public void dropDB(ConnectContext context, String dbName) throws MetaNotFoundExc
database = getDB(context, dbName);
} catch (Exception e) {
LOG.error("Failed to access database {}", dbName, e);
throw new MetaNotFoundException("Failed to access database " + dbName);
throw new StarRocksConnectorException("Failed to access database " + dbName, e);
}

if (database == null) {
Expand Down Expand Up @@ -217,7 +218,8 @@ public boolean registerTable(ConnectContext context, String dbName, String table
} catch (Exception e) {
LOG.error("Failed to register table {}.{} with metadata file location {}",
dbName, tableName, metadataFileLocation, e);
throw new StarRocksConnectorException("Failed to register table: " + e.getMessage(), e);
throw new StarRocksConnectorException(
String.format("Failed to register table %s.%s", dbName, tableName), e);
}
}

Expand Down
Loading
Loading