lỗi và ngoại lệ trong PowerShell là những vật thể có cấu trúc. Thông báo lỗi bạn thấy được in trên bảng điều khiển thực sự là một thông điệp được định dạng với thông tin từ một số phần tử của đối tượng lỗi/ngoại lệ. Bạn có thể (lại) xây dựng nó cho mình như thế này:
$formatstring = "{0} : {1}`n{2}`n" +
" + CategoryInfo : {3}`n" +
" + FullyQualifiedErrorId : {4}`n"
$fields = $_.InvocationInfo.MyCommand.Name,
$_.ErrorDetails.Message,
$_.InvocationInfo.PositionMessage,
$_.CategoryInfo.ToString(),
$_.FullyQualifiedErrorId
$formatstring -f $fields
Nếu bạn chỉ muốn được thông báo lỗi hiển thị trong catch
khối của bạn, bạn có thể chỉ cần echo biến đối tượng hiện tại (mà giữ lỗi tại thời điểm đó):
try {
...
} catch {
$_
}
Nếu bạn cần sử dụng màu đầu ra Write-Host
với một chuỗi định dạng như mô tả ở trên:
try {
...
} catch {
...
Write-Host -Foreground Red -Background Black ($formatstring -f $fields)
}
với những gì đã nói, thông thường bạn don 't muốn chỉ hiển thị thông báo lỗi như là trong một xử lý ngoại lệ (nếu không -ErrorAction Stop
sẽ là vô nghĩa). Các đối tượng lỗi/ngoại lệ có cấu trúc cung cấp cho bạn thông tin bổ sung mà bạn có thể sử dụng để kiểm soát lỗi tốt hơn. Ví dụ: bạn có $_.Exception.HResult
với số lỗi thực tế. $_.ScriptStackTrace
và $_.Exception.StackTrace
, vì vậy bạn có thể hiển thị stacktraces khi gỡ lỗi. $_.Exception.InnerException
cho phép bạn truy cập vào các ngoại lệ lồng nhau thường chứa thông tin bổ sung về lỗi (lỗi PowerShell cấp cao nhất có thể hơi chung chung). Bạn có thể cuộn những trường hợp ngoại lệ lồng với một cái gì đó như thế này:
$e = $_.Exception
$msg = $e.Message
while ($e.InnerException) {
$e = $e.InnerException
$msg += "`n" + $e.Message
}
$msg
Trong trường hợp của bạn các thông tin mà bạn muốn trích xuất có vẻ là trong $_.ErrorDetails.Message
.Đó không phải là khá rõ ràng với tôi nếu bạn có một đối tượng hoặc một chuỗi JSON ở đó, nhưng bạn sẽ có thể để có được thông tin về chủng loại và giá trị của các thành viên của $_.ErrorDetails
bằng cách chạy
$_.ErrorDetails | Get-Member
$_.ErrorDetails | Format-List *
Nếu $_.ErrorDetails.Message
là một đối tượng bạn sẽ có thể để có được những chuỗi tin nhắn như thế này:
$_.ErrorDetails.Message.message
nếu không bạn cần phải chuyển đổi chuỗi JSON để một đối tượng đầu tiên:
$_.ErrorDetails.Message | ConvertFrom-Json | Select-Object -Expand message
Tùy thuộc vào loại lỗi bạn đang xử lý, ngoại lệ của các loại cụ thể cũng có thể bao gồm thông tin cụ thể hơn về sự cố trong tầm tay. Trong trường hợp của bạn ví dụ bạn có một WebException
mà ngoài các thông báo lỗi ($_.Exception.Message
) chứa các phản ứng thực tế từ máy chủ:
PS C:\>$e.Exception | Get-Member
TypeName: System.Net.WebException
Name MemberType Definition
---- ---------- ----------
Equals Method bool Equals(System.Object obj), bool _Exception.E...
GetBaseException Method System.Exception GetBaseException(), System.Excep...
GetHashCode Method int GetHashCode(), int _Exception.GetHashCode()
GetObjectData Method void GetObjectData(System.Runtime.Serialization.S...
GetType Method type GetType(), type _Exception.GetType()
ToString Method string ToString(), string _Exception.ToString()
Data Property System.Collections.IDictionary Data {get;}
HelpLink Property string HelpLink {get;set;}
HResult Property int HResult {get;}
InnerException Property System.Exception InnerException {get;}
Message Property string Message {get;}
Response Property System.Net.WebResponse Response {get;}
Source Property string Source {get;set;}
StackTrace Property string StackTrace {get;}
Status Property System.Net.WebExceptionStatus Status {get;}
TargetSite Property System.Reflection.MethodBase TargetSite {get;}
mà cung cấp cho bạn những thông tin như thế này:
PS C:\>$e.Exception.Response
IsMutuallyAuthenticated : False
Cookies : {}
Headers : {Keep-Alive, Connection, Content-Length, Content-T...}
SupportsHeaders : True
ContentLength : 198
ContentEncoding :
ContentType : text/html; charset=iso-8859-1
CharacterSet : iso-8859-1
Server : Apache/2.4.10
LastModified : 17.07.2016 14:39:29
StatusCode : NotFound
StatusDescription : Not Found
ProtocolVersion : 1.1
ResponseUri : http://www.example.com/
Method : POST
IsFromCache : False
Kể từ không phải tất cả các ngoại lệ đều có cùng một tập hợp các thuộc tính mà bạn có thể muốn sử dụng các trình xử lý cụ thể cho các ngoại lệ cụ thể:
try {
...
} catch [System.ArgumentException] {
# handle argument exceptions
} catch [System.Net.WebException] {
# handle web exceptions
} catch {
# handle all other exceptions
}
Nếu bạn có hoạt động mà cần phải được thực hiện bất kể một lỗi xảy ra hay không (nhiệm vụ dọn dẹp như đóng một ổ cắm hoặc một kết nối cơ sở dữ liệu), bạn có thể đặt chúng trong một khối finally
sau khi xử lý ngoại lệ:
try {
...
} catch {
...
} finally {
# cleanup operations go here
}
tôi đã tìm thấy câu trả lời nhưng điều này là chi tiết hơn nhiều. Chúc mừng. – JustAGuy
Cảm ơn bạn đã giải thích kỹ lưỡng. Rất hữu dụng. –