SharePoint 2010 引入 ExceptionHandlingScope,允許在 ClientContext 批次執行中以 Try/Catch/Finally 結構處理異常,滿足多伺服器請求的錯誤處理需求。
場景:嘗試更新不存在的列表 NonExistingList,捕獲異常後建立該列表,最後在 Finally 更新描述。
public static void ExceptionExample()
{
ClientContext ctx = new ClientContext("https://sp2010u/it");
ExceptionHandlingScope exScope = new ExceptionHandlingScope(ctx);
using (exScope.StartScope())
{
// Try 區塊:嘗試取得並更新列表
using (exScope.StartTry())
{
List myList = ctx.Web.Lists.GetByTitle("NonExistingList");
myList.Description = "這是一段新的描述";
myList.Update();
}
// Catch 區塊:僅在 Try 拋出異常時執行
using (exScope.StartCatch())
{
ListCreationInformation lci = new ListCreationInformation
{
Title = "NonExistingList",
Description = "在 catch 區塊中建立的",
TemplateType = (int)ListTemplateType.GenericList
};
List oList = ctx.Web.Lists.Add(lci);
}
// Finally 區塊:永遠執行
using (exScope.StartFinally())
{
List myList = ctx.Web.Lists.GetByTitle("NonExistingList");
myList.Description = "這是一段在 finally 區塊中建立出來的描述";
myList.Update();
}
}
ctx.ExecuteQuery(); // 批次送出,伺服端依序執行 Try/Catch/Finally
}

可直接貼入 HTML 表單 Web 組件的原始碼編輯器中執行。
<script type="text/ecmascript" language="ecmascript">
var targetWeb, clientContext;
function exceptionExample() {
clientContext = new SP.ClientContext.get_current();
var exScope = new SP.ExceptionHandlingScope(clientContext);
var startScope = exScope.startScope();
var tryScope = exScope.startTry();
// Try
var myList = clientContext.get_web().get_lists().getByTitle("NonExistingList");
myList.set_description("這是一段新描述");
myList.update();
tryScope.dispose();
// Catch
var catchScope = exScope.startCatch();
var lci = new SP.ListCreationInformation();
lci.set_title("NonExistingList");
lci.set_description("在 catch 區塊中建立的描述");
lci.set_templateType(SP.ListTemplateType.genericList);
clientContext.get_web().get_lists().add(lci);
catchScope.dispose();
// Finally
var finallyScope = exScope.startFinally();
myList = clientContext.get_web().get_lists().getByTitle("NonExistingList");
myList.set_description("這是一段在 finally 區塊中建立的描述");
myList.update();
finallyScope.dispose();
startScope.dispose();
clientContext.executeQueryAsync(
Function.createDelegate(this, onSucceededCallback),
Function.createDelegate(this, onFailedCallback));
}
function onSucceededCallback(sender, args) { alert("完成!"); }
function onFailedCallback(sender, args) {
alert('請求失敗. \nError: ' + args.get_message() + '\nStackTrace: ' + args.get_stackTrace());
}
</script>
<input id="Button1" type="button" value="執行代碼" onclick="exceptionExample()" />
dispose() 釋放 Scope 物件。ExecuteQuery (C#) / executeQueryAsync (JS) 為批次提交邊界,伺服端在此時依序執行 Scope 內邏輯。