Skip to content

Commit ac46948

Browse files
committed
Error management for Amazon S3 Source and Sink plugin
1 parent bbd7daf commit ac46948

File tree

3 files changed

+74
-4
lines changed

3 files changed

+74
-4
lines changed
Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
/*
2+
* Copyright © 2025 Cask Data, Inc.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
5+
* use this file except in compliance with the License. You may obtain a copy of
6+
* the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
12+
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
13+
* License for the specific language governing permissions and limitations under
14+
* the License.
15+
*/
16+
17+
package io.cdap.plugin.aws.s3.common;
18+
19+
import com.amazonaws.services.s3.model.AmazonS3Exception;
20+
import com.google.common.base.Throwables;
21+
import io.cdap.cdap.api.exception.ErrorCategory;
22+
import io.cdap.cdap.api.exception.ErrorCodeType;
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.etl.api.exception.ErrorContext;
27+
import io.cdap.cdap.etl.api.exception.ErrorDetailsProvider;
28+
import java.util.List;
29+
30+
/**
31+
* Error details provided for the Amazon S3
32+
**/
33+
public class AmazonErrorDetailsProvider implements ErrorDetailsProvider {
34+
35+
static final String S3_EXTERNAL_DOC = "https://docs.aws.amazon.com/AmazonS3/latest/API/ErrorResponses.html";
36+
37+
@Override
38+
public ProgramFailureException getExceptionDetails(Exception e, ErrorContext errorContext) {
39+
List<Throwable> causalChain = Throwables.getCausalChain(e);
40+
for (Throwable t : causalChain) {
41+
if (t instanceof ProgramFailureException) {
42+
// if causal chain already has program failure exception, return null to avoid double wrap.
43+
return null;
44+
}
45+
if (t instanceof AmazonS3Exception) {
46+
AmazonS3Exception s3Exception = (AmazonS3Exception) t;
47+
String errorMessage = s3Exception.getErrorMessage();
48+
String errorMessageWithDetails = s3Exception.getMessage();
49+
return ErrorUtils.getProgramFailureException(new ErrorCategory(ErrorCategory.ErrorCategoryEnum.PLUGIN),
50+
errorMessage, errorMessageWithDetails, ErrorType.USER, true, ErrorCodeType.HTTP, s3Exception.getErrorCode(),
51+
S3_EXTERNAL_DOC, t);
52+
}
53+
}
54+
return null;
55+
}
56+
}

src/main/java/io/cdap/plugin/aws/s3/sink/S3BatchSink.java

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,8 @@
3131
import io.cdap.cdap.etl.api.batch.BatchSink;
3232
import io.cdap.cdap.etl.api.batch.BatchSinkContext;
3333
import io.cdap.cdap.etl.api.connector.Connector;
34+
import io.cdap.cdap.etl.api.exception.ErrorDetailsProviderSpec;
35+
import io.cdap.plugin.aws.s3.common.AmazonErrorDetailsProvider;
3436
import io.cdap.plugin.aws.s3.common.S3ConnectorConfig;
3537
import io.cdap.plugin.aws.s3.common.S3Constants;
3638
import io.cdap.plugin.aws.s3.common.S3Path;
@@ -78,6 +80,10 @@ public void prepareRun(BatchSinkContext context) throws Exception {
7880
asset = Asset.builder(referenceName)
7981
.setFqn(config.getPath().replace(S3Path.SCHEME, "s3://")).build();
8082

83+
// set error details provider
84+
context.setErrorDetailsProvider(
85+
new ErrorDetailsProviderSpec(AmazonErrorDetailsProvider.class.getName()));
86+
8187
// super is called down here to avoid instantiating the lineage recorder with a null asset
8288
super.prepareRun(context);
8389
}
@@ -207,8 +213,9 @@ public void validate(FailureCollector collector) {
207213
try {
208214
getFilesystemProperties();
209215
} catch (Exception e) {
210-
collector.addFailure("File system properties must be a valid json.", null)
211-
.withConfigProperty(NAME_FILE_SYSTEM_PROPERTIES).withStacktrace(e.getStackTrace());
216+
collector.addFailure(String.format("File system properties must be a valid json, %s, %s",
217+
e.getClass().getName(), e.getMessage()), null)
218+
.withConfigProperty(NAME_FILE_SYSTEM_PROPERTIES).withStacktrace(e.getStackTrace());
212219
}
213220
}
214221
}

src/main/java/io/cdap/plugin/aws/s3/source/S3BatchSource.java

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,8 @@
3030
import io.cdap.cdap.etl.api.batch.BatchSource;
3131
import io.cdap.cdap.etl.api.batch.BatchSourceContext;
3232
import io.cdap.cdap.etl.api.connector.Connector;
33+
import io.cdap.cdap.etl.api.exception.ErrorDetailsProviderSpec;
34+
import io.cdap.plugin.aws.s3.common.AmazonErrorDetailsProvider;
3335
import io.cdap.plugin.aws.s3.common.S3ConnectorConfig;
3436
import io.cdap.plugin.aws.s3.common.S3Constants;
3537
import io.cdap.plugin.aws.s3.common.S3EmptyInputFormat;
@@ -85,6 +87,10 @@ public void prepareRun(BatchSourceContext context) throws Exception {
8587
asset = Asset.builder(referenceName)
8688
.setFqn(config.getPath().replace(S3Path.SCHEME, "s3://")).build();
8789

90+
// set error details provider
91+
context.setErrorDetailsProvider(
92+
new ErrorDetailsProviderSpec(AmazonErrorDetailsProvider.class.getName()));
93+
8894
// super is called down here to avoid instantiating the lineage recorder with a null asset
8995
super.prepareRun(context);
9096
}
@@ -220,8 +226,9 @@ public void validate(FailureCollector collector) {
220226
try {
221227
getFilesystemProperties();
222228
} catch (Exception e) {
223-
collector.addFailure("File system properties must be a valid json.", null)
224-
.withConfigProperty(NAME_FILE_SYSTEM_PROPERTIES).withStacktrace(e.getStackTrace());
229+
collector.addFailure(String.format("File system properties must be a valid json, %s: %s",
230+
e.getClass().getName(), e.getMessage()), null)
231+
.withConfigProperty(NAME_FILE_SYSTEM_PROPERTIES).withStacktrace(e.getStackTrace());
225232
}
226233
}
227234
}

0 commit comments

Comments
 (0)