Donnerstag, 19. Juli 2018

SharePoint "nativehr"-Fehler erklärt

Jeder SharePoint-Entwickler kennt Fehler in der Form:
0x80070718  Your changes could not be saved because this SharePoint Web site has exceeded the storage quota limit.
You must save your work to another location.  Contact your administrator to change the quota limits for the Web site.
Ein Kunde frage neulich: "Woher kommt eigentlich die Zahl (0x80070718) und was bedeutet die?"

Die Frage ist schnell erläutert: Es handelt sich um die hex-Darstellung des HRESULT, welcher der Auslöser des Fehlers war.
Über HRESULT gibt es reichlich Informationen. Am besten ist aber, finde ich, diese (generelle Erläuterung für HRESULT und Facilities) in Kombination mit dieser (liste der Fehler-Codes).

Kurz erläutert besteht ein HRESULT aus 32 Bit, wobei die hohen 5 Bit wie folgt bezeichnet sind:
  • S (1 bit): Severity. If set, indicates a failure result. If clear, indicates a success result.
  • R (1 bit): Reserved. If the N bit is clear, this bit MUST be set to 0. If the N bit is set, this bit is defined by the NTSTATUS numbering space (as specified in section 2.3).
  • C (1 bit): Customer. This bit specifies if the value is customer-defined or Microsoft-defined. The bit is set for customer-defined values and clear for Microsoft-defined values.
  • N (1 bit): If set, indicates that the error code is an NTSTATUS value (as specified in section 2.3), except that this bit is set. 
  • X (1 bit): Reserved. SHOULD be set to 0.
Es folgen 11 Bit "Facility" und anschließend 16 Bit für den eigentlichen Code.

Der Wichtige Punkt daran ist, dass Customer-Bit: Wenn dieses 0 ist, kommt die Meldung von Microsoft und kann in der o.a. Doku "nachgeschlagen" werden. (Ob das dann hilft, oder nicht...)

Für den angegebenen Fall (0x80070718): In Binär-Darstellung ist die Zahl 10000000000001110000011100010101 - und kann daraus einfach "abgezählt" werden:

SRCNXFacilityCode
10000000000001110000011100010101
Ein Fehler von Microsoft0x7 (7)0x715 (1813)

Wobei die Facility wie in [MS-ERREF] beschrieben einen den Fehler als FACILITY_WIN32 ("This region is reserved to map undecorated error codes into HRESULTs.") Fehler beschreibt und der Code, wie bei den SystemErrorCodes beschrieben einen ERROR_NOT_ENOUGH_QUOTA Fehler beschreibt.

Es handelt sich also um einen "generellen" Win32-Fehler, bei dem nicht genügend Quota vorhanden ist. Hat das geholfen? Nicht wirklich, denn das stand auch schon in der Meldung von SharePoint... Aber es ist erklärt...

Da "Abzählen" von Bits nicht immer einfach oder schnell ist, habe ich ein kleines PowerShell Skript geschrieben, dass die "Analyse" erstellen kann:

<#
  .SYNOPSIS
   Decode HResult (hr) codes.. or die trying...
 
  .EXAMPLE
   Decode-HResult 0x80070718
   Shows info about "Quota Exceeded"...
#>

[CmdletBinding()]
param(
    [Parameter(Position=0)]
    [int]$hr
)

function bitshift {
 # https://stackoverflow.com/questions/35116636/bit-shifting-in-powershell-2-0
    param(
        [Parameter(Position=0)]
        [int]$x,

        [Parameter(ParameterSetName='Left')]
        [int]$Left,

        [Parameter(ParameterSetName='Right')]
        [int]$Right
    ) 

    $shift = if($PSCmdlet.ParameterSetName -eq 'Left')
    { 
        $Left
    }
    else
    {
        -$Right
    }

    return [math]::Floor($x * [math]::Pow(2,$shift))
}

$i = [int]$hr
$hex = "0x$([Convert]::ToString($i, 16))"
$bin = [Convert]::ToString($i, 2)

write-verbose "code as int: $i"
write-verbose "code as hex: $hex"
write-verbose "code as bin: $bin"
write-verbose ""
write-verbose "decoding:"
write-verbose $bin.PadLeft(32, " ")
write-verbose "SRCNX|- facil -||---- code ----|"

## see https://en.wikipedia.org/wiki/HRESULT
## and https://msdn.microsoft.com/en-us/library/cc231198.aspx
## and https://docs.microsoft.com/en-us/windows/desktop/com/structure-of-com-error-codes

# lowest 2 bytes for code
$code = $i -band 0xffff
# then 11 bit for facility
$fac = $i -band 0x7ff0000
if($fac -ne 0) { $fac = (bitshift $fac -Right 16)}
# 2 bit reserved, then 1 bit for customer 
$cust = $i -band 0x20000000
if($cust -ne 0x0) { $cust = (bitshift $cust -Right 29)}
# 1 bit reserved (severe?) then 1 bit success (probably always 1?)
$nok = $i -band 0x80000000
if($nok -ne 0) { $nok = 1 }

write-host "hr = $hex"
write-host "Severity: $( if($nok -ne 0){"Fail"} else {"Success"} )"
write-host "code: 0x$([Convert]::ToString($code, 16))"
write-host "facility: 0x$([Convert]::ToString($fac, 16))"
if($cust -eq 0) {
 write-host "the code was Microsoft-defined. "
 Write-host "  So you can lookup facility ($fac) under https://msdn.microsoft.com/en-us/library/cc231198.aspx"
 write-host "  and the code ($code) under https://docs.microsoft.com/en-us/windows/desktop/debug/system-error-codes"
} else {
 write-host "the code was Cutomer-defined"
}


Keine Kommentare:

Kommentar veröffentlichen