Enhance SFTP error handling in SftpController and SftpService by introducing a method to format SftpException messages. Improve listFiles method to handle empty paths and provide clearer error messages in response to exceptions.
This commit is contained in:
@@ -1,5 +1,6 @@
|
||||
package com.sshmanager.controller;
|
||||
|
||||
import com.jcraft.jsch.SftpException;
|
||||
import com.sshmanager.dto.SftpFileInfo;
|
||||
import com.sshmanager.entity.Connection;
|
||||
import com.sshmanager.entity.User;
|
||||
@@ -78,13 +79,28 @@ public class SftpController {
|
||||
.collect(Collectors.toList());
|
||||
return ResponseEntity.ok(dtos);
|
||||
} catch (Exception e) {
|
||||
log.warn("SFTP list failed: connectionId={}, path={}", connectionId, path, e);
|
||||
String errorMsg = toSftpErrorMessage(e, path, "list");
|
||||
log.warn("SFTP list failed: connectionId={}, path={}, error={}", connectionId, path, errorMsg, e);
|
||||
Map<String, String> err = new HashMap<>();
|
||||
err.put("error", e.getMessage() != null ? e.getMessage() : "List failed");
|
||||
err.put("error", errorMsg);
|
||||
return ResponseEntity.status(500).body(err);
|
||||
}
|
||||
}
|
||||
|
||||
private String toSftpErrorMessage(Exception e, String path, String operation) {
|
||||
if (e.getMessage() != null && !e.getMessage().trim().isEmpty()) {
|
||||
return e.getMessage();
|
||||
}
|
||||
Throwable cause = e.getCause();
|
||||
if (cause instanceof SftpException) {
|
||||
return SftpService.formatSftpExceptionMessage((SftpException) cause, path, operation);
|
||||
}
|
||||
if (e instanceof SftpException) {
|
||||
return SftpService.formatSftpExceptionMessage((SftpException) e, path, operation);
|
||||
}
|
||||
return operation + " failed";
|
||||
}
|
||||
|
||||
@GetMapping("/pwd")
|
||||
public ResponseEntity<Map<String, String>> pwd(
|
||||
@RequestParam Long connectionId,
|
||||
|
||||
@@ -3,6 +3,7 @@ package com.sshmanager.service;
|
||||
import com.jcraft.jsch.ChannelSftp;
|
||||
import com.jcraft.jsch.JSch;
|
||||
import com.jcraft.jsch.Session;
|
||||
import com.jcraft.jsch.SftpException;
|
||||
import com.sshmanager.entity.Connection;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
@@ -93,20 +94,59 @@ public class SftpService {
|
||||
}
|
||||
|
||||
public List<FileInfo> listFiles(SftpSession sftpSession, String path) throws Exception {
|
||||
Vector<?> entries = sftpSession.getChannel().ls(path);
|
||||
List<FileInfo> result = new ArrayList<>();
|
||||
for (Object obj : entries) {
|
||||
ChannelSftp.LsEntry entry = (ChannelSftp.LsEntry) obj;
|
||||
String name = entry.getFilename();
|
||||
if (".".equals(name) || "..".equals(name)) continue;
|
||||
result.add(new FileInfo(
|
||||
name,
|
||||
entry.getAttrs().isDir(),
|
||||
entry.getAttrs().getSize(),
|
||||
entry.getAttrs().getMTime() * 1000L
|
||||
));
|
||||
String listPath = (path == null || path.trim().isEmpty()) ? "." : path.trim();
|
||||
try {
|
||||
Vector<?> entries = sftpSession.getChannel().ls(listPath);
|
||||
List<FileInfo> result = new ArrayList<>();
|
||||
for (Object obj : entries) {
|
||||
ChannelSftp.LsEntry entry = (ChannelSftp.LsEntry) obj;
|
||||
String name = entry.getFilename();
|
||||
if (".".equals(name) || "..".equals(name)) continue;
|
||||
result.add(new FileInfo(
|
||||
name,
|
||||
entry.getAttrs().isDir(),
|
||||
entry.getAttrs().getSize(),
|
||||
entry.getAttrs().getMTime() * 1000L
|
||||
));
|
||||
}
|
||||
return result;
|
||||
} catch (SftpException e) {
|
||||
String msg = formatSftpExceptionMessage(e, listPath, "list");
|
||||
throw new RuntimeException(msg, e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Build a user-visible message from JSch SftpException (getMessage() is often null).
|
||||
*/
|
||||
public static String formatSftpExceptionMessage(SftpException e, String path, String operation) {
|
||||
int id = e.getId();
|
||||
String serverMsg = e.getMessage();
|
||||
String reason = sftpErrorCodeToMessage(id);
|
||||
StringBuilder sb = new StringBuilder();
|
||||
sb.append(reason);
|
||||
if (path != null && !path.isEmpty()) {
|
||||
sb.append(": ").append(path);
|
||||
}
|
||||
if (serverMsg != null && !serverMsg.trim().isEmpty()) {
|
||||
sb.append(" (").append(serverMsg).append(")");
|
||||
} else {
|
||||
sb.append(" [SFTP status ").append(id).append("]");
|
||||
}
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
private static String sftpErrorCodeToMessage(int id) {
|
||||
switch (id) {
|
||||
case 2: return "No such file or directory";
|
||||
case 3: return "Permission denied";
|
||||
case 4: return "Operation failed";
|
||||
case 5: return "Bad message";
|
||||
case 6: return "No connection";
|
||||
case 7: return "Connection lost";
|
||||
case 8: return "Operation not supported";
|
||||
default: return "SFTP error";
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
public byte[] download(SftpSession sftpSession, String remotePath) throws Exception {
|
||||
|
||||
Reference in New Issue
Block a user