mirror of
https://github.com/halo-dev/plugin-s3.git
synced 2025-10-15 14:40:46 +00:00
perf: improve more friendly exception messages (#113)
```release-note 友好地提示异常信息 ``` fixes https://github.com/halo-dev/plugin-s3/issues/105 验证方法: 1. ak/sk乱输,发生接收到403状态码(接收错误状态码) 2. endpoint网址改成不存在的,如.com改成.comaaa(未知主机) 3. endpoint端口改成没监听的(超时)
This commit is contained in:
42
src/main/java/run/halo/s3os/S3ExceptionHandler.java
Normal file
42
src/main/java/run/halo/s3os/S3ExceptionHandler.java
Normal file
@@ -0,0 +1,42 @@
|
||||
package run.halo.s3os;
|
||||
|
||||
import lombok.experimental.UtilityClass;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.web.server.ServerWebInputException;
|
||||
import software.amazon.awssdk.core.exception.SdkException;
|
||||
import software.amazon.awssdk.services.s3.model.S3Exception;
|
||||
|
||||
@Slf4j
|
||||
@UtilityClass
|
||||
public class S3ExceptionHandler {
|
||||
|
||||
/**
|
||||
* Map user configuration caused S3 exception to ServerWebInputException
|
||||
* @param throwable Exception
|
||||
* @return ServerWebInputException or original exception
|
||||
*/
|
||||
public static Throwable map(Throwable throwable) {
|
||||
if (throwable instanceof S3Exception s3e) {
|
||||
log.error("S3Exception occurred", s3e);
|
||||
return new ServerWebInputException(String.format(
|
||||
"The object storage service returned an error status code %d. Please check the storage "
|
||||
+ "policy configuration and make sure your account and service are working properly.",
|
||||
s3e.statusCode()));
|
||||
}
|
||||
if (throwable instanceof SdkException sdke && sdke.getMessage() != null
|
||||
&& sdke.getMessage().contains("UnknownHostException")) {
|
||||
log.error("UnknownHostException occurred", sdke);
|
||||
return new ServerWebInputException(
|
||||
"Received an UnknownHostException, please check if the endpoint is entered correctly, "
|
||||
+ "especially for any spaces before or after the endpoint.");
|
||||
}
|
||||
if (throwable instanceof SdkException sdke && sdke.getMessage() != null
|
||||
&& sdke.getMessage().contains("Connect timed out")) {
|
||||
log.error("ConnectTimeoutException occurred", sdke);
|
||||
return new ServerWebInputException(
|
||||
"Received a ConnectTimeoutException, please check if the endpoint is entered correctly, "
|
||||
+ "and make sure your object storage service is working properly.");
|
||||
}
|
||||
return throwable;
|
||||
}
|
||||
}
|
@@ -1,5 +1,13 @@
|
||||
package run.halo.s3os;
|
||||
|
||||
import static run.halo.s3os.S3OsAttachmentHandler.OBJECT_KEY;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.atomic.AtomicBoolean;
|
||||
import java.util.concurrent.atomic.AtomicReference;
|
||||
import java.util.function.Function;
|
||||
import java.util.stream.Collectors;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
@@ -9,38 +17,18 @@ import org.springframework.security.core.context.ReactiveSecurityContextHolder;
|
||||
import org.springframework.security.core.context.SecurityContext;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.web.server.ResponseStatusException;
|
||||
import org.springframework.web.util.UriUtils;
|
||||
import reactor.core.publisher.Flux;
|
||||
import reactor.core.publisher.Mono;
|
||||
import reactor.core.scheduler.Schedulers;
|
||||
import run.halo.app.core.extension.attachment.Attachment;
|
||||
import run.halo.app.core.extension.attachment.Constant;
|
||||
import run.halo.app.core.extension.attachment.Policy;
|
||||
import run.halo.app.extension.ConfigMap;
|
||||
import run.halo.app.extension.Metadata;
|
||||
import run.halo.app.extension.ReactiveExtensionClient;
|
||||
import run.halo.app.infra.utils.JsonUtils;
|
||||
import software.amazon.awssdk.auth.credentials.AwsBasicCredentials;
|
||||
import software.amazon.awssdk.regions.Region;
|
||||
import software.amazon.awssdk.services.s3.S3Client;
|
||||
import software.amazon.awssdk.services.s3.S3Configuration;
|
||||
import software.amazon.awssdk.services.s3.model.HeadObjectRequest;
|
||||
import software.amazon.awssdk.services.s3.model.ListObjectsV2Request;
|
||||
import software.amazon.awssdk.services.s3.model.S3Object;
|
||||
|
||||
import java.net.URI;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.UUID;
|
||||
import java.util.concurrent.atomic.AtomicBoolean;
|
||||
import java.util.concurrent.atomic.AtomicReference;
|
||||
import java.util.function.Function;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import static run.halo.s3os.S3OsAttachmentHandler.OBJECT_KEY;
|
||||
|
||||
|
||||
@Service
|
||||
@RequiredArgsConstructor
|
||||
@@ -103,7 +91,8 @@ public class S3LinkServiceImpl implements S3LinkService {
|
||||
listObjectsV2Response.nextContinuationToken(),
|
||||
listObjectsV2Response.isTruncated()));
|
||||
});
|
||||
});
|
||||
})
|
||||
.onErrorMap(S3ExceptionHandler::map);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -155,7 +144,8 @@ public class S3LinkServiceImpl implements S3LinkService {
|
||||
.getKey() : null, tokenState.currToken,
|
||||
limitedObjects.size() == pageSize);
|
||||
});
|
||||
});
|
||||
})
|
||||
.onErrorMap(S3ExceptionHandler::map);
|
||||
}
|
||||
|
||||
record TokenState(String currToken, String nextToken) {
|
||||
@@ -200,6 +190,7 @@ public class S3LinkServiceImpl implements S3LinkService {
|
||||
.flatMap(client::create)
|
||||
.thenReturn(new LinkResult.LinkResultItem(objectKey, true, null));
|
||||
}))
|
||||
.onErrorMap(S3ExceptionHandler::map)
|
||||
.onErrorResume(throwable ->
|
||||
Mono.just(new LinkResult.LinkResultItem(objectKey, false, throwable.getMessage())));
|
||||
}
|
||||
|
@@ -82,7 +82,8 @@ public class S3OsAttachmentHandler implements AttachmentHandler {
|
||||
final var properties = getProperties(context.configMap());
|
||||
return upload(context, properties)
|
||||
.subscribeOn(Schedulers.boundedElastic())
|
||||
.map(objectDetail -> this.buildAttachment(properties, objectDetail));
|
||||
.map(objectDetail -> this.buildAttachment(properties, objectDetail))
|
||||
.onErrorMap(S3ExceptionHandler::map);
|
||||
});
|
||||
}
|
||||
|
||||
@@ -116,6 +117,7 @@ public class S3OsAttachmentHandler implements AttachmentHandler {
|
||||
})
|
||||
.thenReturn(context);
|
||||
})
|
||||
.onErrorMap(S3ExceptionHandler::map)
|
||||
.map(DeleteContext::attachment);
|
||||
}
|
||||
|
||||
@@ -152,7 +154,8 @@ public class S3OsAttachmentHandler implements AttachmentHandler {
|
||||
}
|
||||
},
|
||||
SdkPresigner::close)
|
||||
.subscribeOn(Schedulers.boundedElastic());
|
||||
.subscribeOn(Schedulers.boundedElastic())
|
||||
.onErrorMap(S3ExceptionHandler::map);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@@ -1,6 +1,5 @@
|
||||
package run.halo.s3os;
|
||||
|
||||
import java.time.Instant;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
Reference in New Issue
Block a user