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;
|
package com.sshmanager.controller;
|
||||||
|
|
||||||
|
import com.jcraft.jsch.SftpException;
|
||||||
import com.sshmanager.dto.SftpFileInfo;
|
import com.sshmanager.dto.SftpFileInfo;
|
||||||
import com.sshmanager.entity.Connection;
|
import com.sshmanager.entity.Connection;
|
||||||
import com.sshmanager.entity.User;
|
import com.sshmanager.entity.User;
|
||||||
@@ -78,13 +79,28 @@ public class SftpController {
|
|||||||
.collect(Collectors.toList());
|
.collect(Collectors.toList());
|
||||||
return ResponseEntity.ok(dtos);
|
return ResponseEntity.ok(dtos);
|
||||||
} catch (Exception e) {
|
} 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<>();
|
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);
|
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")
|
@GetMapping("/pwd")
|
||||||
public ResponseEntity<Map<String, String>> pwd(
|
public ResponseEntity<Map<String, String>> pwd(
|
||||||
@RequestParam Long connectionId,
|
@RequestParam Long connectionId,
|
||||||
|
|||||||
@@ -3,6 +3,7 @@ package com.sshmanager.service;
|
|||||||
import com.jcraft.jsch.ChannelSftp;
|
import com.jcraft.jsch.ChannelSftp;
|
||||||
import com.jcraft.jsch.JSch;
|
import com.jcraft.jsch.JSch;
|
||||||
import com.jcraft.jsch.Session;
|
import com.jcraft.jsch.Session;
|
||||||
|
import com.jcraft.jsch.SftpException;
|
||||||
import com.sshmanager.entity.Connection;
|
import com.sshmanager.entity.Connection;
|
||||||
import org.springframework.stereotype.Service;
|
import org.springframework.stereotype.Service;
|
||||||
|
|
||||||
@@ -93,7 +94,9 @@ public class SftpService {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public List<FileInfo> listFiles(SftpSession sftpSession, String path) throws Exception {
|
public List<FileInfo> listFiles(SftpSession sftpSession, String path) throws Exception {
|
||||||
Vector<?> entries = sftpSession.getChannel().ls(path);
|
String listPath = (path == null || path.trim().isEmpty()) ? "." : path.trim();
|
||||||
|
try {
|
||||||
|
Vector<?> entries = sftpSession.getChannel().ls(listPath);
|
||||||
List<FileInfo> result = new ArrayList<>();
|
List<FileInfo> result = new ArrayList<>();
|
||||||
for (Object obj : entries) {
|
for (Object obj : entries) {
|
||||||
ChannelSftp.LsEntry entry = (ChannelSftp.LsEntry) obj;
|
ChannelSftp.LsEntry entry = (ChannelSftp.LsEntry) obj;
|
||||||
@@ -107,6 +110,43 @@ public class SftpService {
|
|||||||
));
|
));
|
||||||
}
|
}
|
||||||
return result;
|
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";
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public byte[] download(SftpSession sftpSession, String remotePath) throws Exception {
|
public byte[] download(SftpSession sftpSession, String remotePath) throws Exception {
|
||||||
|
|||||||
Reference in New Issue
Block a user