Esempio n. 1
0
    // ReSharper disable once FunctionComplexityOverflow
    internal static ErrorOrNoticeMessage Load(NpgsqlReadBuffer buf, bool includeDetail)
    {
        (string?severity, string?invariantSeverity, string?code, string?message, string?detail, string?hint) = (null, null, null, null, null, null);
        var(position, internalPosition)      = (0, 0);
        (string?internalQuery, string?where) = (null, null);
        (string?schemaName, string?tableName, string?columnName, string?dataTypeName, string?constraintName) =
            (null, null, null, null, null);
        (string?file, string?line, string?routine) = (null, null, null);

        while (true)
        {
            var fieldCode = (ErrorFieldTypeCode)buf.ReadByte();
            switch (fieldCode)
            {
            case ErrorFieldTypeCode.Done:
                // Null terminator; error message fully consumed.
                goto End;

            case ErrorFieldTypeCode.Severity:
                severity = buf.ReadNullTerminatedStringRelaxed();
                break;

            case ErrorFieldTypeCode.InvariantSeverity:
                invariantSeverity = buf.ReadNullTerminatedStringRelaxed();
                break;

            case ErrorFieldTypeCode.Code:
                code = buf.ReadNullTerminatedStringRelaxed();
                break;

            case ErrorFieldTypeCode.Message:
                message = buf.ReadNullTerminatedStringRelaxed();
                break;

            case ErrorFieldTypeCode.Detail:
                detail = buf.ReadNullTerminatedStringRelaxed();
                if (!includeDetail && !string.IsNullOrEmpty(detail))
                {
                    detail = $"Detail redacted as it may contain sensitive data. Specify '{NpgsqlConnectionStringBuilder.IncludeExceptionDetailDisplayName}' in the connection string to include this information.";
                }
                break;

            case ErrorFieldTypeCode.Hint:
                hint = buf.ReadNullTerminatedStringRelaxed();
                break;

            case ErrorFieldTypeCode.Position:
                var positionStr = buf.ReadNullTerminatedStringRelaxed();
                if (!int.TryParse(positionStr, out var tmpPosition))
                {
                    Logger.LogWarning("Non-numeric position in ErrorResponse: " + positionStr);
                    continue;
                }
                position = tmpPosition;
                break;

            case ErrorFieldTypeCode.InternalPosition:
                var internalPositionStr = buf.ReadNullTerminatedStringRelaxed();
                if (!int.TryParse(internalPositionStr, out var internalPositionTmp))
                {
                    Logger.LogWarning("Non-numeric position in ErrorResponse: " + internalPositionStr);
                    continue;
                }
                internalPosition = internalPositionTmp;
                break;

            case ErrorFieldTypeCode.InternalQuery:
                internalQuery = buf.ReadNullTerminatedStringRelaxed();
                break;

            case ErrorFieldTypeCode.Where:
                where = buf.ReadNullTerminatedStringRelaxed();
                break;

            case ErrorFieldTypeCode.File:
                file = buf.ReadNullTerminatedStringRelaxed();
                break;

            case ErrorFieldTypeCode.Line:
                line = buf.ReadNullTerminatedStringRelaxed();
                break;

            case ErrorFieldTypeCode.Routine:
                routine = buf.ReadNullTerminatedStringRelaxed();
                break;

            case ErrorFieldTypeCode.SchemaName:
                schemaName = buf.ReadNullTerminatedStringRelaxed();
                break;

            case ErrorFieldTypeCode.TableName:
                tableName = buf.ReadNullTerminatedStringRelaxed();
                break;

            case ErrorFieldTypeCode.ColumnName:
                columnName = buf.ReadNullTerminatedStringRelaxed();
                break;

            case ErrorFieldTypeCode.DataTypeName:
                dataTypeName = buf.ReadNullTerminatedStringRelaxed();
                break;

            case ErrorFieldTypeCode.ConstraintName:
                constraintName = buf.ReadNullTerminatedStringRelaxed();
                break;

            default:
                // Unknown error field; consume and discard.
                buf.ReadNullTerminatedStringRelaxed();
                break;
            }
        }

End:
        if (severity == null)
        {
            throw new NpgsqlException("Severity not received in server error message");
        }
        if (code == null)
        {
            throw new NpgsqlException("Code not received in server error message");
        }
        if (message == null)
        {
            throw new NpgsqlException("Message not received in server error message");
        }

        return(new ErrorOrNoticeMessage(
                   severity, invariantSeverity ?? severity, code, message,
                   detail, hint, position, internalPosition, internalQuery, where,
                   schemaName, tableName, columnName, dataTypeName, constraintName,
                   file, line, routine));
    }