/// <summary> /// Seeks to the end of the writer stream in each of the writers in the /// content holders. /// </summary> /// /// <param name="contentHolders"> /// The content holders that contain the writers to be moved. /// </param> /// /// <exception cref="ProviderInvocationException"> /// If calling Seek on the content writer throws an exception. /// </exception> /// internal override void SeekContentPosition(List <ContentHolder> contentHolders) { foreach (ContentHolder holder in contentHolders) { if (holder.Writer != null) { try { holder.Writer.Seek(0, System.IO.SeekOrigin.End); } catch (Exception e) // Catch-all OK, 3rd party callout { ProviderInvocationException providerException = new ProviderInvocationException( "ProviderSeekError", SessionStateStrings.ProviderSeekError, holder.PathInfo.Provider, holder.PathInfo.Path, e); // Log a provider health event MshLog.LogProviderHealthEvent( this.Context, holder.PathInfo.Provider.Name, providerException, Severity.Warning); throw providerException; } } } } // SeekContentPosition
private void DisposeCommands() { this.stopping = true; this.FlushLog(); if (this._commands != null) { for (int i = 0; i < this._commands.Count; i++) { CommandProcessorBase base2 = this._commands[i]; if (base2 != null) { try { base2.CommandRuntime.RemoveVariableListsInPipe(); base2.Dispose(); } catch (Exception exception) { CommandProcessorBase.CheckForSevereException(exception); InvocationInfo myInvocation = null; if (base2.Command != null) { myInvocation = base2.Command.MyInvocation; } ProviderInvocationException innerException = exception as ProviderInvocationException; if (innerException != null) { exception = new CmdletProviderInvocationException(innerException, myInvocation); } else { exception = new CmdletInvocationException(exception, myInvocation); MshLog.LogCommandHealthEvent(base2.Command.Context, exception, Severity.Warning); } this.RecordFailure(exception, base2.Command); } } } } this._commands = null; if (this._redirectionPipes != null) { foreach (PipelineProcessor processor in this._redirectionPipes) { try { if (processor != null) { processor.Dispose(); } } catch (Exception exception3) { CommandProcessorBase.CheckForSevereException(exception3); } } } this._redirectionPipes = null; }
internal void CloseContent(List <ContentCommandBase.ContentHolder> contentHolders, bool disposing) { if (contentHolders != null) { foreach (ContentCommandBase.ContentHolder contentHolder in contentHolders) { try { if (contentHolder.Writer != null) { contentHolder.Writer.Close(); } } catch (Exception exception1) { Exception exception = exception1; CommandsCommon.CheckForSevereException(this, exception); ProviderInvocationException providerInvocationException = new ProviderInvocationException("ProviderContentCloseError", SessionStateStrings.ProviderContentCloseError, contentHolder.PathInfo.Provider, contentHolder.PathInfo.Path, exception); MshLog.LogProviderHealthEvent(base.Context, contentHolder.PathInfo.Provider.Name, providerInvocationException, Severity.Warning); if (!disposing) { base.WriteError(new ErrorRecord(providerInvocationException.ErrorRecord, providerInvocationException)); } } try { if (contentHolder.Reader != null) { contentHolder.Reader.Close(); } } catch (Exception exception3) { Exception exception2 = exception3; CommandsCommon.CheckForSevereException(this, exception2); ProviderInvocationException providerInvocationException1 = new ProviderInvocationException("ProviderContentCloseError", SessionStateStrings.ProviderContentCloseError, contentHolder.PathInfo.Provider, contentHolder.PathInfo.Path, exception2); MshLog.LogProviderHealthEvent(base.Context, contentHolder.PathInfo.Provider.Name, providerInvocationException1, Severity.Warning); if (!disposing) { base.WriteError(new ErrorRecord(providerInvocationException1.ErrorRecord, providerInvocationException1)); } } } return; } else { throw PSTraceSource.NewArgumentNullException("contentHolders"); } }
public void ThrowTerminatingError(ErrorRecord errorRecord) { using (PSTransactionManager.GetEngineProtectionScope()) { if (errorRecord == null) { throw CmdletProvider.providerBaseTracer.NewArgumentNullException(nameof(errorRecord)); } if (errorRecord.ErrorDetails != null && errorRecord.ErrorDetails.TextLookupError != null) { Exception textLookupError = errorRecord.ErrorDetails.TextLookupError; errorRecord.ErrorDetails.TextLookupError = (Exception)null; MshLog.LogProviderHealthEvent(this.Context.ExecutionContext, this.ProviderInfo.Name, textLookupError, Severity.Warning); } ProviderInvocationException invocationException = new ProviderInvocationException(this.ProviderInfo, errorRecord); MshLog.LogProviderHealthEvent(this.Context.ExecutionContext, this.ProviderInfo.Name, (Exception)invocationException, Severity.Warning); throw invocationException; } }
public void ThrowTerminatingError(ErrorRecord errorRecord) { using (PSTransactionManager.GetEngineProtectionScope()) { if (errorRecord == null) { throw PSTraceSource.NewArgumentNullException("errorRecord"); } if ((errorRecord.ErrorDetails != null) && (errorRecord.ErrorDetails.TextLookupError != null)) { Exception textLookupError = errorRecord.ErrorDetails.TextLookupError; errorRecord.ErrorDetails.TextLookupError = null; MshLog.LogProviderHealthEvent(this.Context.ExecutionContext, this.ProviderInfo.Name, textLookupError, Severity.Warning); } ProviderInvocationException exception2 = new ProviderInvocationException(this.ProviderInfo, errorRecord); MshLog.LogProviderHealthEvent(this.Context.ExecutionContext, this.ProviderInfo.Name, exception2, Severity.Warning); throw exception2; } }
internal override void SeekContentPosition(List <ContentCommandBase.ContentHolder> contentHolders) { foreach (ContentCommandBase.ContentHolder contentHolder in contentHolders) { if (contentHolder.Writer == null) { continue; } try { contentHolder.Writer.Seek((long)0, SeekOrigin.End); } catch (Exception exception1) { Exception exception = exception1; CommandsCommon.CheckForSevereException(this, exception); ProviderInvocationException providerInvocationException = new ProviderInvocationException("ProviderSeekError", SessionStateStrings.ProviderSeekError, contentHolder.PathInfo.Provider, contentHolder.PathInfo.Path, exception); MshLog.LogProviderHealthEvent(base.Context, contentHolder.PathInfo.Provider.Name, providerInvocationException, Severity.Warning); throw providerInvocationException; } } }
/// <summary> /// Closes the content readers and writers in the content holder array /// </summary> internal void CloseContent(List <ContentHolder> contentHolders, bool disposing) { if (contentHolders == null) { throw PSTraceSource.NewArgumentNullException("contentHolders"); } foreach (ContentHolder holder in contentHolders) { try { if (holder.Writer != null) { holder.Writer.Close(); } } catch (Exception e) // Catch-all OK. 3rd party callout { // Catch all the exceptions caused by closing the writer // and write out an error. ProviderInvocationException providerException = new ProviderInvocationException( "ProviderContentCloseError", SessionStateStrings.ProviderContentCloseError, holder.PathInfo.Provider, holder.PathInfo.Path, e); // Log a provider health event MshLog.LogProviderHealthEvent( this.Context, holder.PathInfo.Provider.Name, providerException, Severity.Warning); if (!disposing) { WriteError( new ErrorRecord( providerException.ErrorRecord, providerException)); } } try { if (holder.Reader != null) { holder.Reader.Close(); } } catch (Exception e) // Catch-all OK. 3rd party callout { // Catch all the exceptions caused by closing the writer // and write out an error. ProviderInvocationException providerException = new ProviderInvocationException( "ProviderContentCloseError", SessionStateStrings.ProviderContentCloseError, holder.PathInfo.Provider, holder.PathInfo.Path, e); // Log a provider health event MshLog.LogProviderHealthEvent( this.Context, holder.PathInfo.Provider.Name, providerException, Severity.Warning); if (!disposing) { WriteError( new ErrorRecord( providerException.ErrorRecord, providerException)); } } } }
/// <summary> /// Appends the content to the specified item. /// </summary> protected override void ProcessRecord() { CmdletProviderContext currentContext = GetCurrentContext(); // Initialize the content if (_content == null) { _content = Array.Empty <object>(); } if (_pipingPaths) { // Make sure to clean up the content writers that are already there if (contentStreams != null && contentStreams.Count > 0) { CloseContent(contentStreams, false); _contentWritersOpen = false; contentStreams = new List <ContentHolder>(); } } if (!_contentWritersOpen) { // Since the paths are being pipelined in, we have // to get new content writers for the new paths string[] paths = GetAcceptedPaths(Path, currentContext); if (paths.Length > 0) { BeforeOpenStreams(paths); contentStreams = GetContentWriters(paths, currentContext); SeekContentPosition(contentStreams); } _contentWritersOpen = true; } // Now write the content to the item try { foreach (ContentHolder holder in contentStreams) { if (holder.Writer != null) { IList result = null; try { result = holder.Writer.Write(_content); } catch (Exception e) // Catch-all OK. 3rd party callout { ProviderInvocationException providerException = new ProviderInvocationException( "ProviderContentWriteError", SessionStateStrings.ProviderContentWriteError, holder.PathInfo.Provider, holder.PathInfo.Path, e); // Log a provider health event MshLog.LogProviderHealthEvent( this.Context, holder.PathInfo.Provider.Name, providerException, Severity.Warning); WriteError( new ErrorRecord( providerException.ErrorRecord, providerException)); continue; } if (result != null && result.Count > 0 && PassThru) { WriteContentObject(result, result.Count, holder.PathInfo, currentContext); } } } } finally { // Need to close all the writers if the paths are being pipelined if (_pipingPaths) { CloseContent(contentStreams, false); _contentWritersOpen = false; contentStreams = new List <ContentHolder>(); } } }
/// <summary> /// Scan forwards to get the tail content. /// </summary> /// <param name="holder"></param> /// <param name="currentContext"></param> /// <returns> /// true if no error occured /// false if there was an error /// </returns> private bool ScanForwardsForTail(ContentHolder holder, CmdletProviderContext currentContext) { var fsReader = holder.Reader as FileSystemContentReaderWriter; Dbg.Diagnostics.Assert(fsReader != null, "Tail is only supported for FileSystemContentReaderWriter"); var tailResultQueue = new Queue <object>(); IList results = null; ErrorRecord error = null; do { try { results = fsReader.ReadWithoutWaitingChanges(ReadCount); } catch (Exception e) { ProviderInvocationException providerException = new ProviderInvocationException( "ProviderContentReadError", SessionStateStrings.ProviderContentReadError, holder.PathInfo.Provider, holder.PathInfo.Path, e); // Log a provider health event MshLog.LogProviderHealthEvent( this.Context, holder.PathInfo.Provider.Name, providerException, Severity.Warning); // Create and save the error record. The error record // will be written outside the while loop. // This is to make sure the accumulated results get written // out before the error record when the 'scanForwardForTail' is true. error = new ErrorRecord( providerException.ErrorRecord, providerException); break; } if (results != null && results.Count > 0) { foreach (object entry in results) { if (tailResultQueue.Count == Tail) { tailResultQueue.Dequeue(); } tailResultQueue.Enqueue(entry); } } } while (results != null && results.Count > 0); if (tailResultQueue.Count > 0) { // Respect the ReadCount parameter. // Output single object when ReadCount == 1; Output array otherwise int count = 0; if (ReadCount <= 0 || (ReadCount >= tailResultQueue.Count && ReadCount != 1)) { count = tailResultQueue.Count; // Write out the content as an array of objects WriteContentObject(tailResultQueue.ToArray(), count, holder.PathInfo, currentContext); } else if (ReadCount == 1) { // Write out the content as single object while (tailResultQueue.Count > 0) { WriteContentObject(tailResultQueue.Dequeue(), count++, holder.PathInfo, currentContext); } } else // ReadCount < Queue.Count { while (tailResultQueue.Count >= ReadCount) { var outputList = new List <object>((int)ReadCount); for (int idx = 0; idx < ReadCount; idx++, count++) { outputList.Add(tailResultQueue.Dequeue()); } // Write out the content as an array of objects WriteContentObject(outputList.ToArray(), count, holder.PathInfo, currentContext); } int remainder = tailResultQueue.Count; if (remainder > 0) { // Write out the content as an array of objects WriteContentObject(tailResultQueue.ToArray(), count, holder.PathInfo, currentContext); } } } if (error != null) { WriteError(error); return(false); } return(true); }
/// <summary> /// Gets the content of an item at the specified path. /// </summary> protected override void ProcessRecord() { // TotalCount and Tail should not be specified at the same time. // Throw out terminating error if this is the case. if (_totalCountSpecified && _tailSpecified) { string errMsg = StringUtil.Format(SessionStateStrings.GetContent_TailAndHeadCannotCoexist, "TotalCount", "Tail"); ErrorRecord error = new ErrorRecord(new InvalidOperationException(errMsg), "TailAndHeadCannotCoexist", ErrorCategory.InvalidOperation, null); WriteError(error); return; } if (TotalCount == 0) { // Don't read anything return; } // Get the content readers CmdletProviderContext currentContext = CmdletProviderContext; contentStreams = this.GetContentReaders(Path, currentContext); try { // Iterate through the content holders reading the content foreach (ContentHolder holder in contentStreams) { long countRead = 0; Dbg.Diagnostics.Assert( holder.Reader != null, "All holders should have a reader assigned"); if (_tailSpecified && !(holder.Reader is FileSystemContentReaderWriter)) { string errMsg = SessionStateStrings.GetContent_TailNotSupported; ErrorRecord error = new ErrorRecord(new InvalidOperationException(errMsg), "TailNotSupported", ErrorCategory.InvalidOperation, Tail); WriteError(error); continue; } // If Tail is negative, we are supposed to read all content out. This is same // as reading forwards. So we read forwards in this case. // If Tail is positive, we seek the right position. Or, if the seek failed // because of an unsupported encoding, we scan forward to get the tail content. if (Tail >= 0) { bool seekSuccess = false; try { seekSuccess = SeekPositionForTail(holder.Reader); } catch (Exception e) { ProviderInvocationException providerException = new ProviderInvocationException( "ProviderContentReadError", SessionStateStrings.ProviderContentReadError, holder.PathInfo.Provider, holder.PathInfo.Path, e); // Log a provider health event MshLog.LogProviderHealthEvent( this.Context, holder.PathInfo.Provider.Name, providerException, Severity.Warning); WriteError(new ErrorRecord( providerException.ErrorRecord, providerException)); continue; } // If the seek was successful, we start to read forwards from that // point. Otherwise, we need to scan forwards to get the tail content. if (!seekSuccess && !ScanForwardsForTail(holder, currentContext)) { continue; } } if (TotalCount != 0) { IList results = null; do { long countToRead = ReadCount; // Make sure we only ask for the amount the user wanted // I am using TotalCount - countToRead so that I don't // have to worry about overflow if ((TotalCount > 0) && (countToRead == 0 || (TotalCount - countToRead < countRead))) { countToRead = TotalCount - countRead; } try { results = holder.Reader.Read(countToRead); } catch (Exception e) // Catch-all OK. 3rd party callout { ProviderInvocationException providerException = new ProviderInvocationException( "ProviderContentReadError", SessionStateStrings.ProviderContentReadError, holder.PathInfo.Provider, holder.PathInfo.Path, e); // Log a provider health event MshLog.LogProviderHealthEvent( this.Context, holder.PathInfo.Provider.Name, providerException, Severity.Warning); WriteError(new ErrorRecord( providerException.ErrorRecord, providerException)); break; } if (results != null && results.Count > 0) { countRead += results.Count; if (ReadCount == 1) { // Write out the content as a single object WriteContentObject(results[0], countRead, holder.PathInfo, currentContext); } else { // Write out the content as an array of objects WriteContentObject(results, countRead, holder.PathInfo, currentContext); } } } while (results != null && results.Count > 0 && ((TotalCount < 0) || countRead < TotalCount)); } } } finally { // close all the content readers CloseContent(contentStreams, false); // Empty the content holder array contentStreams = new List <ContentHolder>(); } }
} // GetResourceString #endregion IResourceSupplier #region ThrowTerminatingError /// <Content contentref="System.Management.Automation.Cmdlet.ThrowTerminatingError" /> public void ThrowTerminatingError(ErrorRecord errorRecord) { using (PSTransactionManager.GetEngineProtectionScope()) { if (null == errorRecord) { throw PSTraceSource.NewArgumentNullException("errorRecord"); } if (null != errorRecord.ErrorDetails && null != errorRecord.ErrorDetails.TextLookupError) { Exception textLookupError = errorRecord.ErrorDetails.TextLookupError; errorRecord.ErrorDetails.TextLookupError = null; MshLog.LogProviderHealthEvent( this.Context.ExecutionContext, ProviderInfo.Name, textLookupError, Severity.Warning); } // We can't play the same game as Cmdlet.ThrowTerminatingError // and save the exception in the "pipeline". We need to pass // the actual exception as a thrown exception. So, we wrap // it in ProviderInvocationException. ProviderInvocationException providerInvocationException = new ProviderInvocationException(ProviderInfo, errorRecord); // Log a provider health event MshLog.LogProviderHealthEvent( this.Context.ExecutionContext, ProviderInfo.Name, providerInvocationException, Severity.Warning); throw providerInvocationException; } }
protected override void ProcessRecord() { CmdletProviderContext currentContext = base.GetCurrentContext(); if (this.content == null) { this.content = new object[0]; } if (this.pipingPaths && this.contentStreams != null && this.contentStreams.Count > 0) { base.CloseContent(this.contentStreams, false); this.contentWritersOpen = false; this.contentStreams = new List <ContentCommandBase.ContentHolder>(); } if (!this.contentWritersOpen) { string[] acceptedPaths = this.GetAcceptedPaths(base.Path, currentContext); if ((int)acceptedPaths.Length > 0) { this.BeforeOpenStreams(acceptedPaths); this.contentStreams = this.GetContentWriters(acceptedPaths, currentContext); this.SeekContentPosition(this.contentStreams); } this.contentWritersOpen = true; } try { foreach (ContentCommandBase.ContentHolder contentStream in this.contentStreams) { if (contentStream.Writer == null) { continue; } IList lists = null; try { lists = contentStream.Writer.Write(this.content); } catch (Exception exception1) { Exception exception = exception1; CommandsCommon.CheckForSevereException(this, exception); ProviderInvocationException providerInvocationException = new ProviderInvocationException("ProviderContentWriteError", SessionStateStrings.ProviderContentWriteError, contentStream.PathInfo.Provider, contentStream.PathInfo.Path, exception); MshLog.LogProviderHealthEvent(base.Context, contentStream.PathInfo.Provider.Name, providerInvocationException, Severity.Warning); base.WriteError(new ErrorRecord(providerInvocationException.ErrorRecord, providerInvocationException)); continue; } if (lists == null || lists.Count <= 0 || !base.PassThru) { continue; } base.WriteContentObject(lists, (long)lists.Count, contentStream.PathInfo, currentContext); } } finally { if (this.pipingPaths) { base.CloseContent(this.contentStreams, false); this.contentWritersOpen = false; this.contentStreams = new List <ContentCommandBase.ContentHolder>(); } } }
protected override void ProcessRecord() { if (!this._totalCountSpecified || !this._tailSpecified) { if (this.TotalCount != (long)0) { CmdletProviderContext cmdletProviderContext = this.CmdletProviderContext; this.contentStreams = base.GetContentReaders(base.Path, cmdletProviderContext); try { Label0: foreach (ContentCommandBase.ContentHolder contentStream in this.contentStreams) { long count = (long)0; if (!this._tailSpecified || contentStream.Reader as FileSystemContentReaderWriter != null) { if (this.Tail >= 0) { bool flag = false; try { flag = this.SeekPositionForTail(contentStream.Reader); } catch (Exception exception1) { Exception exception = exception1; CommandsCommon.CheckForSevereException(this, exception); ProviderInvocationException providerInvocationException = new ProviderInvocationException("ProviderContentReadError", SessionStateStrings.ProviderContentReadError, contentStream.PathInfo.Provider, contentStream.PathInfo.Path, exception); MshLog.LogProviderHealthEvent(base.Context, contentStream.PathInfo.Provider.Name, providerInvocationException, Severity.Warning); base.WriteError(new ErrorRecord(providerInvocationException.ErrorRecord, providerInvocationException)); continue; } if (!flag && !this.ScanForwardsForTail(contentStream, cmdletProviderContext)) { continue; } } if (this.TotalCount == (long)0) { continue; } IList lists = null; do { long readCount = this.ReadCount; if (this.TotalCount > (long)0 && this.TotalCount - readCount < count) { readCount = this.TotalCount - count; } try { lists = contentStream.Reader.Read(readCount); } catch (Exception exception3) { Exception exception2 = exception3; CommandsCommon.CheckForSevereException(this, exception2); ProviderInvocationException providerInvocationException1 = new ProviderInvocationException("ProviderContentReadError", SessionStateStrings.ProviderContentReadError, contentStream.PathInfo.Provider, contentStream.PathInfo.Path, exception2); MshLog.LogProviderHealthEvent(base.Context, contentStream.PathInfo.Provider.Name, providerInvocationException1, Severity.Warning); base.WriteError(new ErrorRecord(providerInvocationException1.ErrorRecord, providerInvocationException1)); goto Label0; } if (lists == null || lists.Count <= 0) { continue; } count = count + (long)lists.Count; if (this.ReadCount != (long)1) { base.WriteContentObject(lists, count, contentStream.PathInfo, cmdletProviderContext); } else { base.WriteContentObject(lists[0], count, contentStream.PathInfo, cmdletProviderContext); } }while (lists != null && lists.Count > 0 && (this.TotalCount < (long)0 || count < this.TotalCount)); } else { string getContentTailNotSupported = SessionStateStrings.GetContent_TailNotSupported; ErrorRecord errorRecord = new ErrorRecord(new InvalidOperationException(getContentTailNotSupported), "TailNotSupported", ErrorCategory.InvalidOperation, (object)this.Tail); base.WriteError(errorRecord); } } } finally { base.CloseContent(this.contentStreams, false); this.contentStreams = new List <ContentCommandBase.ContentHolder>(); } return; } else { return; } } else { string str = StringUtil.Format(SessionStateStrings.GetContent_TailAndHeadCannotCoexist, "TotalCount", "Tail"); ErrorRecord errorRecord1 = new ErrorRecord(new InvalidOperationException(str), "TailAndHeadCannotCoexist", ErrorCategory.InvalidOperation, null); base.WriteError(errorRecord1); return; } }
private bool ScanForwardsForTail(ContentCommandBase.ContentHolder holder, CmdletProviderContext currentContext) { FileSystemContentReaderWriter reader = holder.Reader as FileSystemContentReaderWriter; Queue <object> objs = new Queue <object>(); IList lists = null; ErrorRecord errorRecord = null; do { try { lists = reader.ReadWithoutWaitingChanges(this.ReadCount); } catch (Exception exception1) { Exception exception = exception1; CommandsCommon.CheckForSevereException(this, exception); ProviderInvocationException providerInvocationException = new ProviderInvocationException("ProviderContentReadError", SessionStateStrings.ProviderContentReadError, holder.PathInfo.Provider, holder.PathInfo.Path, exception); MshLog.LogProviderHealthEvent(base.Context, holder.PathInfo.Provider.Name, providerInvocationException, Severity.Warning); errorRecord = new ErrorRecord(providerInvocationException.ErrorRecord, providerInvocationException); break; } if (lists == null || lists.Count <= 0) { continue; } foreach (object obj in lists) { if (objs.Count == this.Tail) { objs.Dequeue(); } objs.Enqueue(obj); } }while (lists != null && lists.Count > 0); if (objs.Count > 0) { int count = 0; if (this.ReadCount <= (long)0 || this.ReadCount >= (long)objs.Count && this.ReadCount != (long)1) { count = objs.Count; ArrayList arrayLists = new ArrayList(); while (objs.Count > 0) { arrayLists.Add(objs.Dequeue()); } base.WriteContentObject(arrayLists.ToArray(), (long)count, holder.PathInfo, currentContext); } else { if (this.ReadCount != (long)1) { while ((long)objs.Count >= this.ReadCount) { ArrayList arrayLists1 = new ArrayList(); int num = 0; while ((long)num < this.ReadCount) { arrayLists1.Add(objs.Dequeue()); num++; count++; } base.WriteContentObject(arrayLists1.ToArray(), (long)count, holder.PathInfo, currentContext); } int count1 = objs.Count; if (count1 > 0) { ArrayList arrayLists2 = new ArrayList(); while (count1 > 0) { arrayLists2.Add(objs.Dequeue()); count1--; count++; } base.WriteContentObject(arrayLists2.ToArray(), (long)count, holder.PathInfo, currentContext); } } else { while (objs.Count > 0) { int num1 = count; count = num1 + 1; base.WriteContentObject(objs.Dequeue(), (long)num1, holder.PathInfo, currentContext); } } } } if (errorRecord == null) { return(true); } else { base.WriteError(errorRecord); return(false); } }