Search application error logs¶
clsAppErrorCollection exposes three GetAppErrorCollection factory overloads that all converge on the same criteria-driven retrieve: an optional date or date-range filter, optional machine/app/environment/user filters, and an optional full-text search term are assembled into a dynamic WHERE clause, then executed as a paired row query (capped at 300 rows) and count query.
| Field | Value |
|---|---|
| Operation ID | OP-LV-04 |
| Trigger | Caller calls GetAppErrorCollection(inDataportal, inErrorDate), GetAppErrorCollection(inCriteria), or GetAppErrorCollection(inDataportal, inErrorDate, inMachineName, inEnvironment, inAppName, inUserName) |
| Inputs | IDataPortalInfo; optional ErrorDate, StartDate/EndDate range, MachineName, AppName, Environment, UserName, SearchText, OrderByField, OrderByDir on the Criteria object |
| Outputs | clsAppErrorCollection populated with up to 300 clsAppError child objects; TotalCount set to the full matching row count |
| Primary components | clsAppErrorCollection.GetAppErrorCollection (three overloads), clsAppErrorCollection.Criteria.BuildWhere, clsAppErrorCollection.Criteria.BuildOrder, clsAppErrorCollection.Criteria.GetSearchValue, clsAppErrorCollection.BeforeRetrieve, clsAppErrorCollection.AfterRetrieve |
| Entry point | Application\SAIF.Application.LogView\clsAppErrorCollection.vb |
Steps¶
- Select an entry overload. The simplest overload takes only an
ErrorDateand wraps it in a newCriteria; the caller-supplied-criteria overload passes a pre-builtCriteriastraight through; the five-filter overload constructs aCriteriaand assignsErrorDate,MachineName,Environment,AppName, andUserNamebefore retrieving. All three ultimately callinDataportal.DataAccessLayer.RetrieveObject(...)with aCriteriainstance. - Build the
WHEREclause (BuildWhere). - Date filtering: if both
StartDateandEndDateare set (greater thanDate.MinValue), add an inclusive range predicateError_Date >= '<StartDate 00:00>' and Error_Date <= '<EndDate 23:59>'built by direct string formatting (not a bound parameter). Otherwise, if a singleErrorDateis set, addcast(cast(Error_Date as varchar(11)) as datetime) = @ErrorDateto match on the date portion only. - Machine/app filters: if
MachineNameorAppNameis non-empty and does not contain the literal[ALL], add an equality predicate for that field (BR-002). - Environment filter: if
Environmentis non-empty and not[ALL], split on;and build the value directly into a quotedIN (...)list (BR-003). - User filter: if
UserNamecontains;, split it the same way into anIN (...)list; otherwise add a singlelike @UserNamepredicate. - Full-text filter: if
SearchTextis non-empty, appendCONTAINS((Error_Info, State_Info, Error_Source), @SEARCHTEXT)(BR-004). - Any leading
ANDproduced by the assembly is trimmed from the final string. - Normalize the search text (
GetSearchValue), whenSearchTextis supplied. - Strip double and single quotes from the raw search text.
- Split the remaining text on spaces, commas, and semicolons.
- If the original text contains any of the logic-operator tokens (
" AND ","&"," OR ","|","&!"), preserve each recognized operator token unquoted and wrap every other token in double quotes. - Otherwise, wrap every token in double quotes and join them with
AND. - The resulting expression is bound to
@SEARCHTEXTon both the row query and the count query. - Build the sort clause (
BuildOrder), row query only. IfOrderByFieldis set, look it up (case-insensitively, by property name or column name) in theSortableFieldsdictionary (AppName,DeletedFlag,Environment,ErrorDate,MachineName,PageName,UserName,ErrorSource) and appendASCorDESCperOrderByDir(defaultDescending). IfOrderByFieldis empty, default toORDER BY Error_Date DESC. - If
OrderByFielddoes not match any known field, the LINQ lookup returns an empty string and the resultingORDER BYclause has no column before the sort direction, which is not valid SQL syntax as constructed.* - Configure the retrieve requests (
BeforeRetrieve). Two data requests are queued in the same call: aResultSetrequest usingRetrieveSQL(SELECT TOP 300 ...plus the builtWHERE/ORDER BY) (SQL-005, App_Error) (BR-001), and aScalarrequest usingRetrieveSQLCount(SELECT Count(*) ...with the sameWHERE) (SQL-006, App_Error). Both bind@ErrorDate(only when in range),@MachineName,@Username,@AppName, and@SEARCHTEXT(only whenSearchTextis non-empty). - Load the results (
AfterRetrieve). For every row in the first result set, create a newclsAppError, callLoad(...)on it (which fills fields and marks the object old), and add it to the collection viaMyBase.Add. SetTotalCountfrom the second (scalar count) request. ClearMyCriteria.IsDirty.
Process flow¶
The following diagram visualizes the filter-build, execute, and load sequence.
flowchart TD
Start([Caller calls GetAppErrorCollection]) --> Build[BuildWhere: date, machine,<br>app, environment, user, search-text predicates]
Build --> Search{SearchText supplied?}
Search -->|Yes| Normalize[GetSearchValue: strip quotes,<br>tokenize, preserve logic operators]
Search -->|No| Order
Normalize --> Order[BuildOrder: map OrderByField<br>via SortableFields or default Error_Date DESC]
Order --> Rows[Execute TOP 300 row query]
Rows --> Count[Execute matching COUNT query]
Count --> Load[Load each row into a<br>new clsAppError; set TotalCount]
Load --> Done([Collection and TotalCount returned])
Failure and edge-case behavior¶
- The row query is hard-capped at 300 rows (BR-001) even when
TotalCountreports more matches, so a caller filtering on a broad range never sees the full result set through the row query alone. - The start/end date range predicate is built by direct string concatenation of formatted dates rather than a bound parameter, unlike every other filter in
BuildWhere.* - An unrecognized
OrderByFieldvalue produces a syntactically incompleteORDER BYclause (no column name before the sort direction), which would fail at execution rather than silently falling back to the default sort.* UserNamefiltering branches on whether the value contains;: a single value useslike @UserName(partial match), while multiple semicolon-delimited values use an exactIN (...)list — the matching semantics differ between the single- and multi-value cases.*SearchTextnormalization strips all quote characters from the raw input before tokenizing, so a search phrase intended to be treated as a single literal loses any caller-supplied quoting.
Related documentation¶
Note: Statements marked with
*were inferred from code structure, naming conventions, or contextual evidence where direct confirmation was not available in source artifacts.
Sources¶
Application\SAIF.Application.LogView\clsAppErrorCollection.vbApplication\SAIF.Application.LogView\modLogViewExtensions.vb