Skip to content

Commit

Permalink
Finished implementing new logger.exception() JS function
Browse files Browse the repository at this point in the history
  • Loading branch information
jongpie committed Sep 30, 2024
1 parent 8967ed2 commit fd156e7
Show file tree
Hide file tree
Showing 5 changed files with 113 additions and 6 deletions.
10 changes: 5 additions & 5 deletions docs/lightning-components/LogEntryBuilder.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
- [.setError(error)](#LogEntryBuilder+setError) [<code>LogEntryBuilder</code>](#LogEntryBuilder)
- [.setExceptionDetails(exception)](#LogEntryBuilder+setExceptionDetails) [<code>LogEntryBuilder</code>](#LogEntryBuilder)
- [.setField(fieldToValue)](#LogEntryBuilder+setField) [<code>LogEntryBuilder</code>](#LogEntryBuilder)
- [.parseStackTrace(error)](#LogEntryBuilder+parseStackTrace) [<code>LogEntryBuilder</code>](#LogEntryBuilder)
- [.parseStackTrace(originStackTraceError)](#LogEntryBuilder+parseStackTrace) [<code>LogEntryBuilder</code>](#LogEntryBuilder)
- [.addTag(tag)](#LogEntryBuilder+addTag) [<code>LogEntryBuilder</code>](#LogEntryBuilder)
- [.addTags(tags)](#LogEntryBuilder+addTags) [<code>LogEntryBuilder</code>](#LogEntryBuilder)
- [.getComponentLogEntry()](#LogEntryBuilder+getComponentLogEntry) <code>ComponentLogEntry</code>
Expand Down Expand Up @@ -127,16 +127,16 @@ Sets multiple field values on the builder's `LogEntryEvent__e` record

<a name="LogEntryBuilder+parseStackTrace"></a>

### logEntryBuilder.parseStackTrace(error) [<code>LogEntryBuilder</code>](#LogEntryBuilder)
### logEntryBuilder.parseStackTrace(originStackTraceError) [<code>LogEntryBuilder</code>](#LogEntryBuilder)

Parses the provided error's stack trace and sets the log entry's origin & stack trace fields

**Kind**: instance method of [<code>LogEntryBuilder</code>](#LogEntryBuilder)
**Returns**: [<code>LogEntryBuilder</code>](#LogEntryBuilder) - The same instance of `LogEntryBuilder`, useful for chaining methods

| Param | Type | Description |
| ----- | ------------------ | ----------------------------------------------------------------------- |
| error | <code>Error</code> | The instance of a JavaScript `Error` object with a stack trace to parse |
| Param | Type | Description |
| --------------------- | ------------------ | ----------------------------------------------------------------------- |
| originStackTraceError | <code>Error</code> | The instance of a JavaScript `Error` object with a stack trace to parse |

<a name="LogEntryBuilder+addTag"></a>

Expand Down
19 changes: 19 additions & 0 deletions docs/lightning-components/Logger.md
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,10 @@
<dd><p>Sets the scenario name for the current transaction - this is stored in <code>LogEntryEvent__e.Scenario__c</code>
and <code>Log__c.Scenario__c</code>, and can be used to filter &amp; group logs</p>
</dd>
<dt><a href="#exception">exception(message, exception)</a> <code>LogEntryBuilder</code></dt>
<dd><p>Creates a new log entry with logging level == <code>LoggingLevel.ERROR</code>,
automatically saves the log, and then throws the provided exception</p>
</dd>
<dt><a href="#error">error(message)</a> <code>LogEntryBuilder</code></dt>
<dd><p>Creates a new log entry with logging level == <code>LoggingLevel.ERROR</code></p>
</dd>
Expand Down Expand Up @@ -103,6 +107,21 @@ and `Log__c.Scenario__c`, and can be used to filter & group logs
| -------- | ------------------- | ------------------------------------------------------ |
| scenario | <code>String</code> | The name to use for the current transaction's scenario |

<a name="exception"></a>

## exception(message, exception) <code>LogEntryBuilder</code>

Creates a new log entry with logging level == `LoggingLevel.ERROR`,
automatically saves the log, and then throws the provided exception

**Kind**: global function
**Returns**: <code>LogEntryBuilder</code> - The new entry's instance of `LogEntryEventBuilder`, useful for chaining methods

| Param | Type | Description |
| --------- | ------------------- | -------------------------------------------------------------------------------- |
| message | <code>String</code> | The string to use to set the entry's message field |
| exception | <code>Error</code> | The instance of a JavaScript `Error` object to use, or an Apex HTTP error to use |

<a name="error"></a>

## error(message) <code>LogEntryBuilder</code>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -353,6 +353,32 @@ describe('logger lwc recommended sync getLogger() import approach tests', () =>
expect(logEntry.tags.length).toEqual(1);
});

it('auto-saves log & throws exception when using recommended sync getLogger() import approach', async () => {
getSettings.mockResolvedValue({ ...MOCK_GET_SETTINGS });
const logger = getLogger();
// getLogger() is built to be sync, but internally, some async tasks must execute
// before some sync tasks are executed
await flushPromises('Resolve async task queue');
const message = 'some message';
const mockError = new TypeError('oops');
let thrownError;

try {
logger.exception(message, mockError);
} catch (error) {
thrownError = error;
}

expect(thrownError).toBe(mockError);
await flushPromises('Resolve async task queue');
expect(logger.getBufferSize()).toBe(0);
expect(saveComponentLogEntries).toHaveBeenCalledTimes(1);
expect(saveComponentLogEntries.mock.calls[0][0].componentLogEntries.length).toEqual(1);
const savedComponentLogEntry = saveComponentLogEntries.mock.calls[0][0].componentLogEntries[0];
expect(savedComponentLogEntry.loggingLevel).toEqual('ERROR');
expect(savedComponentLogEntry.message).toEqual(message);
});

it('still works for ERROR logging level when disabled when using recommended sync getLogger() import approach', async () => {
getSettings.mockResolvedValue({ ...MOCK_GET_SETTINGS, isEnabled: false });
const logger = getLogger();
Expand Down Expand Up @@ -896,6 +922,29 @@ describe('logger lwc deprecated async createLogger() import tests', () => {
expect(logEntry.tags.length).toEqual(1);
});

it('auto-saves log & throws exception when using deprecated async createLogger() import approach', async () => {
getSettings.mockResolvedValue({ ...MOCK_GET_SETTINGS });
const logger = await createLogger();
const message = 'some message';
const mockError = new TypeError('oops');
let thrownError;

try {
logger.exception(message, mockError);
} catch (error) {
thrownError = error;
}

expect(thrownError).toBe(mockError);
await flushPromises('Resolve async task queue');
expect(logger.getBufferSize()).toBe(0);
expect(saveComponentLogEntries).toHaveBeenCalledTimes(1);
expect(saveComponentLogEntries.mock.calls[0][0].componentLogEntries.length).toEqual(1);
const savedComponentLogEntry = saveComponentLogEntries.mock.calls[0][0].componentLogEntries[0];
expect(savedComponentLogEntry.loggingLevel).toEqual('ERROR');
expect(savedComponentLogEntry.message).toEqual(message);
});

it('still works for ERROR logging level when disabled when using deprecated async createLogger() import approach', async () => {
getSettings.mockResolvedValue({ ...MOCK_GET_SETTINGS, isEnabled: false });
const logger = await createLogger();
Expand Down Expand Up @@ -1429,6 +1478,31 @@ describe('logger lwc legacy markup tests', () => {
expect(logEntry.tags.length).toEqual(1);
});

it('auto-saves log & throws exception when using deprecated markup approach', async () => {
getSettings.mockResolvedValue({ ...MOCK_GET_SETTINGS });
const logger = createElement('c-logger', { is: Logger });
document.body.appendChild(logger);
await flushPromises();
const message = 'some message';
const mockError = new TypeError('oops');
let thrownError;

try {
logger.exception(message, mockError);
} catch (error) {
thrownError = error;
}

expect(thrownError).toBe(mockError);
await flushPromises('Resolve async task queue');
expect(logger.getBufferSize()).toBe(0);
expect(saveComponentLogEntries).toHaveBeenCalledTimes(1);
expect(saveComponentLogEntries.mock.calls[0][0].componentLogEntries.length).toEqual(1);
const savedComponentLogEntry = saveComponentLogEntries.mock.calls[0][0].componentLogEntries[0];
expect(savedComponentLogEntry.loggingLevel).toEqual('ERROR');
expect(savedComponentLogEntry.message).toEqual(message);
});

it('still works for ERROR logging level when disabled when using deprecated markup approach', async () => {
getSettings.mockResolvedValue({ ...MOCK_GET_SETTINGS, isEnabled: false });
const logger = createElement('c-logger', { is: Logger });
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -157,7 +157,7 @@ const LogEntryBuilder = class {

/**
* @description Parses the provided error's stack trace and sets the log entry's origin & stack trace fields
* @param {Error} error The instance of a JavaScript `Error` object with a stack trace to parse
* @param {Error} originStackTraceError The instance of a JavaScript `Error` object with a stack trace to parse
* @return {LogEntryBuilder} The same instance of `LogEntryBuilder`, useful for chaining methods
*/
parseStackTrace(originStackTraceError) {
Expand Down
14 changes: 14 additions & 0 deletions nebula-logger/core/main/logger-engine/lwc/logger/logger.js
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,20 @@ export default class Logger extends LightningElement {
this.#loggerService.setScenario(scenario);
}

/**
* @description Creates a new log entry with logging level == `LoggingLevel.ERROR`,
* automatically saves the log, and then throws the provided exception
* @param {String} message The string to use to set the entry's message field
* @param {Error} exception The instance of a JavaScript `Error` object to use, or an Apex HTTP error to use
* @return {LogEntryBuilder} The new entry's instance of `LogEntryEventBuilder`, useful for chaining methods
*/
@api
exception(message, exception) {
// An error has to be initialized here (in logger.js, not loggerService.js) to use for stack trace parsing
// so that the stack trace is accurate/has full context when the logger LWC is embedded in a component's markup
this.#loggerService.exception(message, exception, new Error());
}

/**
* @description Creates a new log entry with logging level == `LoggingLevel.ERROR`
* @param {String} message The string to use to set the entry's message field
Expand Down

0 comments on commit fd156e7

Please sign in to comment.