COMException 0x81020089 in ItemAdding

(Thanks to my work colleague Cesar for pointing out this case to me)

SYMPTOMS

You have a custom list event receiver in SharePoint. You trap the ItemAdding event and you perform a validation logic to determine if the item should be added to the list. You determine that it’s not the case and you want to inform the user.

So, you set the ErrorMessage property of SPItemEventProperties to the desired text and you set Cancel property to True.

SharePoint throws a COMException 0x81020089 error with or without your error message.

CAUSE

By setting Cancel to True, you are instructing SharePoint to raise an exception. If you don’t treat the exception, it is shown as such and displayed to the end user.

SOLUTION

Set the SPItemEventProperties.Status property to CancelNoError (no error will be shown) or CancelWithError (error will be shown) before setting Cancel to True.

Where to Store those Large Files? A Tale of a BLOB

Few months ago I noticed that the WSS 3.0 introduced the notion of a external file storage provider to SharePoint world. Since then I kept myself updated about it, and I have mixed feelings for it.

The Rationale

If your SharePoint is mainly a glorified File Share, then this may be interesting to you. In essence, SharePoint saves the binary data for your files in SQL Server as BLOBs(Binary Large OBjects). So, it’s easy for the SQL Server database files to grow rapidly in size as you add more and more large binary files.

The Hope

If only we could say to SharePoint not to save that large files into the database but to a file server or a distributed file system…..then we could do as Documentum does, saving the metadata into a database and the binaries to the file system.

The Good News

Well, it’s possible. SharePoint allows us to create our own external binary large object (BLOB) store provider, or EBS Provider. We must inherit from ISPExternalBinaryProvider class and implement our own Save and Load procedures.

ebs_provider

This provider operates deeply in SharePoint infrastructure stack, low enough to be completely transparent to the content and the SharePoint object model.

The Bad News

Unfortunately, too many of them:

  • Currently it can only be configured at SPFarm level, which means that we use it for ALL the lists and libraries or NONE of them. A major screw-up issue that prevents it to be really useful in production.
  • Any updates will create new BLOBs instead of updating the old ones. Want to garbage-collect the old ones? Do it yourself!
  • The code runs outside .NET environment, but it a dreaded COM world. HRESULTs, hex errors, mysterious hangs…..the old friends are welcome again!
  • Microsoft says that SharePoint 2009/2010 might have another implementation of EBS Provider, possibly related to SQL Server 2008 transactional FILESTREAM storage system. No compatibility is assured nor suggested.
  • The performance will almost surely be crippled, compared to SQL Server database storage.

Still Want to Try?

You can find more information on MSDN SharePoint SDK: http://msdn.microsoft.com/en-us/library/bb802976.aspx

COM Again (0x81020037)

I found this “descriptive” error message in a fragment of MOSS 2007 code in a webpart that uploads and tags a document with appropriate metadata:

Microsoft.SharePoint.SPException: DOMAINuser has modified the file Sample.doc
System.Runtime.InteropServices.COMException (0x81020037)

The code 0x81020037 is “Save Conflict” error code in COM. The culprit:

SPListItem doc = list.Add();
doc[“Field1”] = “Value”;
doc[“Field2”] = “Value”;
doc.CheckIn(“Check-in Message”);
doc.Update(); <-- this is the line that throws the error I tried reversing CheckIn and Update methods, with no success. However, the following trick did the job: SPListItem doc = list.Add();
doc[“Field1”] = “Value”;
doc[“Field2”] = “Value”;
doc.CheckIn(“Check-in Message”);
doc = FindByTitle(doc.Title)
doc.Update();

FindByTitle is a custom method I wrote that finds a SPListItem in a SPList, performing a search on the Title field.

The explication: the underlying COM scaffolding doesn’t like the Update() method after CheckIn(). I had to “reacquire” the item and perform the Update() on this new reference to the same document.

Elementary, dear Watson….