Bump version to 1.1.3, add detailed lifecycle logging in debug mode, and enhance error handling in services
This commit is contained in:
@@ -9,7 +9,7 @@ import { findIndex } from '@microsoft/sp-lodash-subset';
|
||||
import { ISPTermStorePickerServiceProps } from './ISPTermStorePickerServiceProps';
|
||||
import { IPickerTerm } from './IPickerTerm';
|
||||
import { ApplicationCustomizerContext } from '@microsoft/sp-application-base';
|
||||
import { debugError } from './MegaMenuDebug';
|
||||
import { debugError, debugLog, debugWarn } from './MegaMenuDebug';
|
||||
|
||||
const EmptyGuid: string = '00000000-0000-0000-0000-000000000000';
|
||||
const TermCachePrefix: string = 'MegaMenu:TermSet:v2:';
|
||||
@@ -38,6 +38,12 @@ export default class SPTermStorePickerService {
|
||||
constructor(private props: ISPTermStorePickerServiceProps, private context: ApplicationCustomizerContext, private debug: boolean = false) {
|
||||
this.clientServiceUrl = this.context.pageContext.web.absoluteUrl + '/_vti_bin/client.svc/ProcessQuery';
|
||||
this.suggestionServiceUrl = this.context.pageContext.web.absoluteUrl + '/_vti_bin/TaxonomyInternalService.json/GetSuggestions';
|
||||
debugLog(this.debug, 'SPTermStorePickerService', 'Service initialized.', {
|
||||
clientServiceUrl: this.clientServiceUrl,
|
||||
termSetNameOrId: this.props.termsetNameOrID,
|
||||
useSessionStorage: this.props.useSessionStorage,
|
||||
cacheMinutes: this.props.cacheMinutes
|
||||
});
|
||||
}
|
||||
|
||||
public async getTermLabels(termId: string): Promise<string[]> {
|
||||
@@ -146,6 +152,13 @@ export default class SPTermStorePickerService {
|
||||
cacheMinutes: number = 15
|
||||
): Promise<ITermSet> {
|
||||
let termsetId: string = termset;
|
||||
debugLog(this.debug, 'SPTermStorePickerService', 'getAllTerms started.', {
|
||||
configuredTermSet: termset,
|
||||
hideDeprecatedTags: hideDeprecatedTags === true,
|
||||
hideTagsNotAvailableForTagging: hideTagsNotAvailableForTagging === true,
|
||||
useSessionStorage: useSessionStorage,
|
||||
cacheMinutes: cacheMinutes
|
||||
});
|
||||
// Check if the provided term set property is a GUID or string
|
||||
if (!this.isGuid(termset)) {
|
||||
// Fetch the term store information
|
||||
@@ -154,7 +167,11 @@ export default class SPTermStorePickerService {
|
||||
const crntTermSet = this.getTermSetId(termStore, termset);
|
||||
if (crntTermSet) {
|
||||
termsetId = this.cleanGuid(crntTermSet.Id);
|
||||
debugLog(this.debug, 'SPTermStorePickerService', 'Term set name resolved to an ID.', {
|
||||
termsetId: termsetId
|
||||
});
|
||||
} else {
|
||||
debugWarn(this.debug, 'SPTermStorePickerService', 'Configured term set could not be resolved.', termset);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
@@ -162,9 +179,18 @@ export default class SPTermStorePickerService {
|
||||
const childTerms = this.getCachedTermSet(termsetId, useSessionStorage);
|
||||
|
||||
if (childTerms) {
|
||||
debugLog(this.debug, 'SPTermStorePickerService', 'Returning terms from session cache.', {
|
||||
termsetId: termsetId,
|
||||
termCount: childTerms.Terms ? childTerms.Terms.length : 0
|
||||
});
|
||||
return childTerms;
|
||||
}
|
||||
|
||||
debugLog(this.debug, 'SPTermStorePickerService', 'No valid cache entry found; sending ProcessQuery request.', {
|
||||
termsetId: termsetId,
|
||||
url: this.clientServiceUrl
|
||||
});
|
||||
|
||||
// Request body to retrieve all terms for the given term set
|
||||
const data = `<Request xmlns="http://schemas.microsoft.com/sharepoint/clientquery/2009" SchemaVersion="15.0.0.0" LibraryVersion="16.0.0.0" ApplicationName="Javascript Library"><Actions><ObjectPath Id="1" ObjectPathId="0" /><ObjectIdentityQuery Id="2" ObjectPathId="0" /><ObjectPath Id="4" ObjectPathId="3" /><ObjectIdentityQuery Id="5" ObjectPathId="3" /><ObjectPath Id="7" ObjectPathId="6" /><ObjectIdentityQuery Id="8" ObjectPathId="6" /><ObjectPath Id="10" ObjectPathId="9" /><Query Id="11" ObjectPathId="6"><Query SelectAllProperties="true"><Properties /></Query></Query><Query Id="12" ObjectPathId="9"><Query SelectAllProperties="false"><Properties /></Query><ChildItemQuery SelectAllProperties="false"><Properties><Property Name="IsRoot" SelectAll="true" /><Property Name="Labels" SelectAll="true" /><Property Name="TermsCount" SelectAll="true" /><Property Name="CustomSortOrder" SelectAll="true" /><Property Name="Id" SelectAll="true" /><Property Name="Name" SelectAll="true" /><Property Name="PathOfTerm" SelectAll="true" /><Property Name="Parent" SelectAll="true" /><Property Name="LocalCustomProperties" SelectAll="true" /><Property Name="IsDeprecated" ScalarProperty="true" /><Property Name="IsAvailableForTagging" ScalarProperty="true" /></Properties></ChildItemQuery></Query></Actions><ObjectPaths><StaticMethod Id="0" Name="GetTaxonomySession" TypeId="{981cbc68-9edc-4f8d-872f-71146fcbb84f}" /><Method Id="3" ParentId="0" Name="GetDefaultSiteCollectionTermStore" /><Method Id="6" ParentId="3" Name="GetTermSet"><Parameters><Parameter Type="Guid">${termsetId}</Parameter></Parameters></Method><Method Id="9" ParentId="6" Name="GetAllTerms" /></ObjectPaths></Request>`;
|
||||
|
||||
@@ -178,6 +204,11 @@ export default class SPTermStorePickerService {
|
||||
};
|
||||
|
||||
return this.context.spHttpClient.post(this.clientServiceUrl, SPHttpClient.configurations.v1, httpPostOptions).then((serviceResponse: SPHttpClientResponse) => {
|
||||
debugLog(this.debug, 'SPTermStorePickerService', 'ProcessQuery response received.', {
|
||||
status: serviceResponse.status,
|
||||
statusText: serviceResponse.statusText,
|
||||
ok: serviceResponse.ok
|
||||
});
|
||||
this.ensureSuccessfulResponse(serviceResponse, 'Terms');
|
||||
return serviceResponse.json().then((serviceJSONResponse: any) => {
|
||||
if (!Array.isArray(serviceJSONResponse)) {
|
||||
@@ -195,11 +226,21 @@ export default class SPTermStorePickerService {
|
||||
let terms = termStoreResultTerms[0]._Child_Items_;
|
||||
|
||||
if (hideDeprecatedTags === true) {
|
||||
const countBeforeDeprecatedFilter: number = terms.length;
|
||||
terms = terms.filter(d => d.IsDeprecated === false);
|
||||
debugLog(this.debug, 'SPTermStorePickerService', 'Deprecated terms filtered.', {
|
||||
before: countBeforeDeprecatedFilter,
|
||||
after: terms.length
|
||||
});
|
||||
}
|
||||
|
||||
if (hideTagsNotAvailableForTagging === true) {
|
||||
const countBeforeAvailableFilter: number = terms.length;
|
||||
terms = terms.filter(d => d.IsAvailableForTagging === true);
|
||||
debugLog(this.debug, 'SPTermStorePickerService', 'Terms unavailable for tagging filtered.', {
|
||||
before: countBeforeAvailableFilter,
|
||||
after: terms.length
|
||||
});
|
||||
}
|
||||
|
||||
// Clean the term ID and specify the path depth
|
||||
@@ -233,12 +274,21 @@ export default class SPTermStorePickerService {
|
||||
value: termStoreResultTermSet
|
||||
};
|
||||
window.sessionStorage.setItem(TermCachePrefix + termsetId, JSON.stringify(cacheEntry));
|
||||
debugLog(this.debug, 'SPTermStorePickerService', 'Term set stored in session cache.', {
|
||||
key: TermCachePrefix + termsetId,
|
||||
expiresAt: cacheEntry.expiresAt
|
||||
});
|
||||
}
|
||||
} catch (error) {
|
||||
// Do nothing, sometimes "storage quota exceeded" error if too many items
|
||||
debugWarn(this.debug, 'SPTermStorePickerService', 'Term cache could not be written.', error);
|
||||
}
|
||||
debugLog(this.debug, 'SPTermStorePickerService', 'getAllTerms completed.', {
|
||||
termsetId: termsetId,
|
||||
termCount: termStoreResultTermSet.Terms ? termStoreResultTermSet.Terms.length : 0
|
||||
});
|
||||
return termStoreResultTermSet;
|
||||
}
|
||||
debugWarn(this.debug, 'SPTermStorePickerService', 'ProcessQuery response contained no term set.');
|
||||
return null;
|
||||
});
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user