Skip to content

Commit 623fa36

Browse files
committed
Adding User and System Errors in FileErrorDetailsProvider
1 parent c15b9e3 commit 623fa36

1 file changed

Lines changed: 117 additions & 1 deletion

File tree

core-plugins/src/main/java/io/cdap/plugin/batch/source/FileErrorDetailsProvider.java

Lines changed: 117 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,11 +16,127 @@
1616

1717
package io.cdap.plugin.batch.source;
1818

19+
import com.google.common.base.Strings;
20+
import com.google.common.base.Throwables;
21+
import com.google.common.collect.ImmutableMap;
22+
import io.cdap.cdap.api.exception.ErrorCategory;
23+
import io.cdap.cdap.api.exception.ErrorType;
24+
import io.cdap.cdap.api.exception.ErrorUtils;
25+
import io.cdap.cdap.api.exception.ProgramFailureException;
26+
import io.cdap.cdap.api.metadata.MetadataException;
27+
import io.cdap.cdap.etl.api.exception.ErrorContext;
1928
import io.cdap.plugin.common.HydratorErrorDetailsProvider;
29+
import org.apache.hadoop.fs.ChecksumException;
30+
import org.apache.hadoop.fs.FileAlreadyExistsException;
31+
import org.apache.hadoop.fs.InvalidPathException;
32+
import org.apache.hadoop.fs.InvalidRequestException;
33+
import org.apache.hadoop.fs.ParentNotDirectoryException;
34+
import org.apache.hadoop.fs.PathIsNotDirectoryException;
35+
import org.apache.hadoop.hdfs.BlockMissingException;
36+
import org.apache.hadoop.hdfs.protocol.QuotaExceededException;
37+
import org.apache.hadoop.hdfs.security.token.block.InvalidBlockTokenException;
38+
import org.apache.hadoop.hdfs.server.datanode.ReplicaNotFoundException;
39+
import org.apache.hadoop.hdfs.server.namenode.SafeModeException;
40+
import org.apache.hadoop.ipc.RemoteException;
41+
import org.apache.hadoop.ipc.StandbyException;
42+
import org.apache.hadoop.security.AccessControlException;
43+
import org.apache.hadoop.util.DiskChecker;
44+
45+
import java.io.FileNotFoundException;
46+
import java.net.NoRouteToHostException;
47+
import java.net.SocketTimeoutException;
48+
import java.util.Collections;
49+
import java.util.HashMap;
50+
import java.util.List;
51+
import java.util.Map;
52+
import java.util.concurrent.TimeoutException;
53+
import javax.annotation.Nullable;
54+
import javax.security.auth.login.FailedLoginException;
2055

2156
/**
2257
* FileErrorDetails provider
2358
*/
2459
public class FileErrorDetailsProvider extends HydratorErrorDetailsProvider {
25-
60+
static final String ERROR_MESSAGE_FORMAT = "Error occurred in the phase: '%s'. %s: %s";
61+
62+
private static final Map<Class<? extends Throwable>, ErrorType> exceptionErrorTypeMap =
63+
new ImmutableMap.Builder<Class<? extends Throwable>, ErrorType>()
64+
.put(FileNotFoundException.class, ErrorType.USER)
65+
.put(AccessControlException.class, ErrorType.USER)
66+
.put(ParentNotDirectoryException.class, ErrorType.USER)
67+
.put(InvalidPathException.class, ErrorType.USER)
68+
.put(FileAlreadyExistsException.class, ErrorType.USER)
69+
.put(QuotaExceededException.class, ErrorType.USER)
70+
.put(PathIsNotDirectoryException.class, ErrorType.USER)
71+
.put(InvalidRequestException.class, ErrorType.USER)
72+
.put(ChecksumException.class, ErrorType.USER)
73+
.put(RemoteException.class, ErrorType.SYSTEM)
74+
.put(SocketTimeoutException.class, ErrorType.SYSTEM)
75+
.put(DiskChecker.DiskOutOfSpaceException.class, ErrorType.SYSTEM)
76+
.put(StandbyException.class, ErrorType.SYSTEM)
77+
.put(NoRouteToHostException.class, ErrorType.SYSTEM)
78+
.put(BlockMissingException.class, ErrorType.SYSTEM)
79+
.put(ReplicaNotFoundException.class, ErrorType.SYSTEM)
80+
.put(InvalidBlockTokenException.class, ErrorType.SYSTEM)
81+
.put(SafeModeException.class, ErrorType.SYSTEM)
82+
.put(TimeoutException.class, ErrorType.SYSTEM)
83+
.put(FailedLoginException.class, ErrorType.SYSTEM)
84+
.put(MetadataException.class, ErrorType.SYSTEM)
85+
.build();
86+
87+
@Override
88+
public ProgramFailureException getExceptionDetails(Exception e, ErrorContext errorContext) {
89+
// Call super method to get base exception details
90+
ProgramFailureException ex = super.getExceptionDetails(e, errorContext);
91+
if (ex != null) {
92+
return ex;
93+
}
94+
return getFileBasedExceptionDetails(e, null, errorContext);
95+
}
96+
97+
private static ProgramFailureException getFileBasedExceptionDetails(Exception e, @Nullable String errorReason,
98+
@Nullable ErrorContext errorContext) {
99+
List<Throwable> causalChain = Throwables.getCausalChain(e);
100+
101+
for (Throwable t : causalChain) {
102+
for (Map.Entry<Class<? extends Throwable>, ErrorType> entry : exceptionErrorTypeMap.entrySet()) {
103+
if (entry.getKey().isInstance(t)) {
104+
return getProgramFailureException((Exception) t, errorContext, entry.getValue(), errorReason, true);
105+
}
106+
}
107+
}
108+
return null;
109+
}
110+
111+
/**
112+
* Retrieves detailed exception information for file-based errors from an exception chain.
113+
*
114+
* @param e The Exception to get the error information from.
115+
* @return A ProgramFailureException with the given error information.
116+
*/
117+
public static ProgramFailureException getFileBasedProgramFailureExceptionDetailsFromChain(Exception e,
118+
@Nullable String errorReason) {
119+
ProgramFailureException ex = getFileBasedExceptionDetails(e, errorReason, null);
120+
if (ex == null) {
121+
return getProgramFailureException(e, null, ErrorType.UNKNOWN, errorReason, false);
122+
}
123+
return ex;
124+
}
125+
126+
/**
127+
* Get a ProgramFailureException with the given error information from {@link Exception}.
128+
*
129+
* @param e The Exception to get the error information from.
130+
* @return A ProgramFailureException with the given error information.
131+
*/
132+
private static ProgramFailureException getProgramFailureException(Exception e, @Nullable ErrorContext errorContext,
133+
ErrorType errorType, @Nullable String errorReason, boolean dependency) {
134+
if (Strings.isNullOrEmpty(errorReason)) {
135+
errorReason = e.getMessage();
136+
}
137+
String errorMessage = e.getMessage();
138+
return ErrorUtils.getProgramFailureException(new ErrorCategory(ErrorCategory.ErrorCategoryEnum.PLUGIN),
139+
errorReason, errorContext != null ? String.format(ERROR_MESSAGE_FORMAT, errorContext.getPhase(), e.getClass()
140+
.getName(), errorMessage) : String.format("%s: %s", e.getClass().getName(), errorMessage), errorType, dependency, e);
141+
}
26142
}

0 commit comments

Comments
 (0)