Skip to content

Commit d6b2928

Browse files
authored
Merge pull request cdapio#1962 from cloudsufi/addingKnownErrorsInFileErrorDetailsProvider
Adding User and System Errors in FileErrorDetailsProvider
2 parents 02ed15e + 7124ab6 commit d6b2928

File tree

1 file changed

+115
-1
lines changed

1 file changed

+115
-1
lines changed

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

Lines changed: 115 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,11 +16,125 @@
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.List;
49+
import java.util.Map;
50+
import java.util.concurrent.TimeoutException;
51+
import javax.annotation.Nullable;
52+
import javax.security.auth.login.FailedLoginException;
2053

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

0 commit comments

Comments
 (0)