feat: Status message customisation#418
Conversation
|
Note Reviews pausedIt looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the Use the following commands to manage reviews:
Use the checkboxes below for quick actions:
WalkthroughIntroduces a structured device-status model: adds ChangesStructured status core
Per-integration status typing & messages
Message factory helpers
Integrations: getStatus migrations
Device core, normalization, and API
Tests & helpers
Sequence Diagram(s)sequenceDiagram
autonumber
participant Integration as Device Integration
participant DeviceInstance as DeviceInstance / Context
participant Normaliser as normaliseDeviceStatus
participant Consumers as Event Consumers
Integration->>DeviceInstance: connectionChanged(status: DeviceStatusInput) / getStatus() -> DeviceStatusInput
DeviceInstance->>Normaliser: normaliseDeviceStatus(statusInput, active?)
Normaliser-->>DeviceInstance: DeviceStatus { statusCode, statusDetails, active }
DeviceInstance->>Consumers: emit normalized DeviceStatus
Estimated code review effort🎯 4 (Complex) | ⏱️ ~60 minutes Possibly related PRs
Suggested labels
Suggested reviewers
✨ Finishing Touches🧪 Generate unit tests (beta)
|
|
@coderabbitai review |
✅ Actions performedReview triggered.
|
There was a problem hiding this comment.
Actionable comments posted: 3
🤖 Fix all issues with AI agents
In `@packages/timeline-state-resolver/README.md`:
- Around line 129-134: The example uses a placeholder comment for the context
parameter type in createMyDeviceError; replace it with a mapped type so the
context is strongly typed (e.g., use MyDeviceErrorContextMap[T] as the context
type) and ensure a MyDeviceErrorContextMap type exists mapping each
MyDeviceErrorCode to its context shape; update the function signature for
createMyDeviceError<T extends MyDeviceErrorCode>(code: T, context:
MyDeviceErrorContextMap[T]): DeviceStatusError<T> and import/declare
MyDeviceErrorContextMap where needed so the example compiles and gives concrete
types for each error code.
In `@packages/timeline-state-resolver/src/deviceErrorMessages.ts`:
- Around line 34-38: The JSDoc example output is inconsistent with the template
interpolation: update the example so the output matches the actual template
behavior used by errorsToMessages; either adjust the allMessages template for
AtemErrorCode.DISCONNECTED to not include {{host}} or change the expected
messages array to include the host (e.g., "ATEM disconnected from
192.168.1.10"); reference the AtemErrorCode.DISCONNECTED entry and the
errorsToMessages/allMessages usage in the example and ensure the example's input
context (host) and expected output align.
In `@packages/timeline-state-resolver/src/index.ts`:
- Around line 12-18: The export lists a non-existent symbol AtemErrorContext
causing the build to fail; update the export block to remove AtemErrorContext
and instead export the actual context types exported by the errors module
(AtemErrorContextMap, AtemDisconnectedContext, AtemPsuFaultContext) or re-export
whichever specific context aliases you need (e.g., export type AtemErrorContext
= AtemErrorContextMap if you prefer a single alias), ensuring the exported
symbols match those declared in the './integrations/atem/errors' module.
🧹 Nitpick comments (1)
packages/timeline-state-resolver/src/__tests__/deviceErrorMessages.spec.ts (1)
11-13: Minor: Test context differs from actual definition.The test defines
host: stringas required, but inerrors.ts,AtemDisconnectedContexthashost?: string(optional). This inconsistency is minor since it doesn't affect test correctness, but consider aligning them for consistency.♻️ Suggested fix
interface AtemDisconnectedContext extends DeviceErrorContextBase { - host: string + host?: string }
📜 Review details
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (10)
packages/timeline-state-resolver-types/src/device.tspackages/timeline-state-resolver-types/src/deviceError.tspackages/timeline-state-resolver-types/src/index.tspackages/timeline-state-resolver/README.mdpackages/timeline-state-resolver/src/__tests__/deviceErrorMessages.spec.tspackages/timeline-state-resolver/src/deviceErrorMessages.tspackages/timeline-state-resolver/src/index.tspackages/timeline-state-resolver/src/integrations/atem/__tests__/atem.spec.tspackages/timeline-state-resolver/src/integrations/atem/errors.tspackages/timeline-state-resolver/src/integrations/atem/index.ts
🧰 Additional context used
🧬 Code graph analysis (4)
packages/timeline-state-resolver-types/src/device.ts (1)
packages/timeline-state-resolver-types/src/deviceError.ts (1)
DeviceStatusError(27-35)
packages/timeline-state-resolver/src/deviceErrorMessages.ts (1)
packages/timeline-state-resolver-types/src/deviceError.ts (1)
DeviceStatusError(27-35)
packages/timeline-state-resolver/src/integrations/atem/errors.ts (1)
packages/timeline-state-resolver-types/src/deviceError.ts (2)
DeviceErrorContextBase(5-8)DeviceStatusError(27-35)
packages/timeline-state-resolver/src/__tests__/deviceErrorMessages.spec.ts (3)
packages/timeline-state-resolver/src/index.ts (2)
AtemErrorCode(14-14)AtemErrorMessages(15-15)packages/timeline-state-resolver-types/src/deviceError.ts (2)
DeviceErrorContextBase(5-8)DeviceStatusError(27-35)packages/timeline-state-resolver/src/deviceErrorMessages.ts (1)
errorsToMessages(40-48)
🪛 GitHub Actions: Node CI
packages/timeline-state-resolver-types/src/deviceError.ts
[error] 1-1: Build failed for timeline-state-resolver:build. Process completed with exit code 130.
packages/timeline-state-resolver/README.md
[error] 1-1: Build failed for timeline-state-resolver:build. Process completed with exit code 130.
packages/timeline-state-resolver/src/index.ts
[error] 17-17: "./integrations/atem/errors" has no exported member named 'AtemErrorContext'. Did you mean 'AtemErrorContextMap'?
[error] 1-1: Build failed for timeline-state-resolver:build. Process completed with exit code 130.
packages/timeline-state-resolver/src/integrations/atem/index.ts
[error] 1-1: Build failed for timeline-state-resolver:build. Process completed with exit code 130.
packages/timeline-state-resolver-types/src/index.ts
[error] 17-17: "./integrations/atem/errors" has no exported member named 'AtemErrorContext'. Did you mean 'AtemErrorContextMap'?
[error] 1-1: Build failed for timeline-state-resolver:build. Process completed with exit code 130.
packages/timeline-state-resolver-types/src/device.ts
[error] 1-1: Build failed for timeline-state-resolver:build. Process completed with exit code 130.
packages/timeline-state-resolver/src/deviceErrorMessages.ts
[error] 1-1: Build failed for timeline-state-resolver:build. Process completed with exit code 130.
packages/timeline-state-resolver/src/integrations/atem/errors.ts
[error] 1-1: Build failed for timeline-state-resolver:build. Process completed with exit code 130.
packages/timeline-state-resolver/src/__tests__/deviceErrorMessages.spec.ts
[error] 1-1: Build failed for timeline-state-resolver:build. Process completed with exit code 130.
packages/timeline-state-resolver/src/integrations/atem/__tests__/atem.spec.ts
[error] 1-1: Build failed for timeline-state-resolver:build. Process completed with exit code 130.
🔇 Additional comments (12)
packages/timeline-state-resolver-types/src/index.ts (1)
55-55: LGTM!The new export follows the established pattern and correctly exposes the
deviceErrormodule types for consumers.packages/timeline-state-resolver/README.md (1)
49-88: Good documentation for the new feature.The documentation clearly explains the structured error system, provides usage examples for blueprints, and shows how to convert errors to messages. This will help consumers understand and adopt the new error handling approach.
packages/timeline-state-resolver-types/src/deviceError.ts (1)
1-35: Well-designed type definitions.The generic interface design with sensible defaults provides flexibility for device-specific implementations while maintaining type safety. The JSDoc documentation clearly explains the naming convention and usage patterns.
packages/timeline-state-resolver-types/src/device.ts (1)
3-3: Clean extension of DeviceStatus.The optional
errorsfield maintains backward compatibility while enabling the new structured error system. The documentation clearly explains the fallback behavior when errors are not present or understood.Also applies to: 15-24
packages/timeline-state-resolver/src/deviceErrorMessages.ts (1)
9-17: Solid implementation.The
interpolatefunction correctly preserves placeholders when values are missing, providing graceful degradation. TheerrorsToMessagesfunction has a sensible fallback to the error code when no template is found.Also applies to: 40-47
packages/timeline-state-resolver/src/integrations/atem/errors.ts (1)
1-68: Well-structured type-safe error system.The implementation follows TypeScript best practices:
- Const object + derived type pattern for error codes ensures type safety
- Context interfaces properly extend
DeviceErrorContextBase- Factory function with generics enforces correct context types per error code
- Message templates use consistent
{{variable}}interpolation syntaxpackages/timeline-state-resolver/src/index.ts (1)
20-37: TODO comment is reasonable for tracking future work.The TODO provides a clear pattern reference and lists all remaining integrations. Consider creating an issue to track this work instead of leaving it in code long-term.
packages/timeline-state-resolver/src/__tests__/deviceErrorMessages.spec.ts (1)
58-148: Comprehensive test coverage forerrorsToMessages.Tests cover all essential scenarios:
- Single and multiple error conversion
- Variable interpolation from context
- Custom template overrides
- Fallback to raw error code when no template exists
- Missing placeholder handling
- Empty array edge case
- Optional
deviceName/deviceIdfields- Cross-device template combination
packages/timeline-state-resolver/src/integrations/atem/__tests__/atem.spec.ts (2)
2-2: Import will work once the build issue inindex.tsis resolved.The import from
'..'correctly references the re-exportedAtemErrorCodeandcreateAtemErrorfrom the ATEM integration barrel.
57-121: Thorough test coverage for the new error structure.The 'Check Status' test comprehensively validates:
- Initial disconnected state produces
DISCONNECTEDerror- Connected state clears errors to
undefined- PSU faults generate
PSU_FAULTerrors with correct context (psuNumber,totalPsus)- Reconnection/disconnect transitions
The assertions for both
messagesanderrorsarrays ensure backward compatibility while validating the new structured error system.packages/timeline-state-resolver/src/integrations/atem/index.ts (2)
39-43: Clean separation of error imports and re-exports.The error-related imports and exports are well-organized, making the error types available for blueprint customization while keeping the implementation details in
errors.ts.
158-188: Well-structured error accumulation and status reporting.The refactored
getStatus()method:
- Properly accumulates errors into a typed array
- Uses early return for disconnected state (appropriate optimization)
- Iterates PSUs with 1-indexed display for human-readable messages
- Derives messages via
errorsToMessagesfor consistency- Returns
errors: undefinedwhen empty (backward compatible)The status code logic correctly prioritizes:
BAD(disconnected) >WARNING_MAJOR(PSU fault) >GOOD.
✏️ Tip: You can disable this entire section by setting review_details to false in your review settings.
f3d719f to
2d26d58
Compare
687fb30 to
099da5e
Compare
|
@coderabbitai review |
✅ Actions performedReview triggered.
|
There was a problem hiding this comment.
Actionable comments posted: 5
🤖 Fix all issues with AI agents
In `@packages/timeline-state-resolver-types/src/index.ts`:
- Around line 29-31: Duplicate export of './integrations/atem' is present;
remove the redundant export line so './integrations/atem' is only exported once
(keep a single export statement for the ATEM integration in index.ts to avoid
duplicate re-exports).
In `@packages/timeline-state-resolver/src/integrations/casparCG/errors.ts`:
- Around line 8-12: The JSDoc example for createCasparCGError uses
CasparCGErrorCode.QUEUE_OVERFLOW but omits required context fields; update the
example to supply the full CasparCGErrorContextMap for QUEUE_OVERFLOW (include
deviceName, host, and port) so it matches the required shape, i.e., modify the
example call to createCasparCGError(CasparCGErrorCode.QUEUE_OVERFLOW, {
deviceName: 'CasparCG 1', host: '192.168.1.10', port: 5250 }) to mirror the
DISCONNECTED example and ensure consistency with CasparCGErrorContextMap.
In `@packages/timeline-state-resolver/src/integrations/casparCG/index.ts`:
- Around line 788-792: The returned status object currently always includes an
errors array which can be empty and is truthy; in the function that returns the
object (the block using statusCode, messages: errorsToMessages(errors,
CasparCGErrorMessages), errors, active: this.isActive) change the construction
so that the errors property is only added when errors.length > 0 (and likewise
omit messages if errors is empty), e.g. build the result object conditionally
and only assign errors when non-empty to match the ATEM integration and avoid
consumers misinterpreting an empty array as an error.
- Around line 760-785: The getStatus() method dereferences this._ccg.host and
this._ccg.port which can be undefined before init() or during teardown; update
getStatus() to safely read host/port (e.g., const host = this._ccg?.host ??
this.initOptions?.host ?? '' and const port = this._ccg?.port ??
this.initOptions?.port ?? '') and use those fallback values when calling
createCasparCGError(CasparCGErrorCode.DISCONNECTED, ...) and
createCasparCGError(CasparCGErrorCode.QUEUE_OVERFLOW, ...) so no property access
on an uninitialized this._ccg occurs.
In `@packages/timeline-state-resolver/src/service/DeviceInstance.ts`:
- Around line 269-272: The constructor currently calls new
deviceSpecs.deviceClass(...) which triggers _getDeviceContextAPI() and reads
this._deviceName before _deviceName is assigned; move the assignment that sets
this._deviceName to occur before instantiating deviceSpecs.deviceClass (i.e.,
set this._deviceName early in the constructor), so _getDeviceContextAPI()
returns the correct name; update any constructor flow that builds the
DeviceContextAPI or calls _getDeviceContextAPI() to happen after this
assignment.
🧹 Nitpick comments (1)
packages/timeline-state-resolver-types/src/templateString.ts (1)
22-29: Consider removing or conditionalizing theconsole.logfor missing values.Line 25 logs a message for every missing placeholder value. This could be noisy in production, especially if:
- Custom templates intentionally use fewer variables than available in context
- Templates are processed frequently
Since this is expected behavior when
leaveUnknownPlaceholdersistrue(placeholders are preserved for later substitution), the log may not always indicate a problem.♻️ Consider removing or making logging conditional
export function interpolateTemplateString( template: string, context: Record<string, any>, - leaveUnknownPlaceholders = false + leaveUnknownPlaceholders = false, + debug = false ): string { return template.replace(/\{\{(\w+)\}\}/g, (match, key) => { const value = context[key] if (value === undefined || value === null) { - console.log(`interpolateTemplateString: missing value for key ${key} in template:`, template) + if (debug) { + console.log(`interpolateTemplateString: missing value for key ${key} in template:`, template) + } return leaveUnknownPlaceholders ? match : key // Keep key or placeholder if no value } return String(value) }) }Alternatively, remove the log entirely since the behavior (preserving placeholder or using key name) is well-documented.
b76e7c4 to
46cf25d
Compare
| * These codes can be customized in blueprints via deviceErrorMessages. | ||
| */ | ||
| export const AtemErrorCode = { | ||
| DISCONNECTED: 'DEVICE_ATEM_DISCONNECTED', |
There was a problem hiding this comment.
Here they are DEVICE_ATEM_DISCONNECTED, in some others they are HTTPWATCHER_KEYWORD_NOT_FOUND. It would be good for that to be consistent
There was a problem hiding this comment.
Changed to always start DEVICE_
bea7594 to
ec334bd
Compare
|
@coderabbitai review |
de8eb8b to
945a3c6
Compare
|
There was a problem hiding this comment.
Actionable comments posted: 2
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (1)
packages/timeline-state-resolver/src/integrations/websocketClient/__tests__/websocketClient.spec.ts (1)
112-122:⚠️ Potential issue | 🟡 Minor | ⚡ Quick winAdd assertions for both mocked
connectionStatus()branches.These two mocks are currently unused, so the test doesn’t actually verify the legacy
messages-based return path or status transitions. Addexpect(device.getStatus()).toEqual(...)after each mock setup.Suggested patch
//@ts-expect-error - is set to private MockWebSocketConnection.prototype.isWsConnected = true jest.spyOn(WebSocketConnection.prototype, 'connectionStatus').mockReturnValue({ statusCode: StatusCode.GOOD, messages: ['WS Connected'], }) + expect(device.getStatus()).toEqual({ + statusCode: StatusCode.GOOD, + messages: ['WS Connected'], + }) //@ts-expect-error - is set to private MockWebSocketConnection.prototype.isWsConnected = false jest.spyOn(WebSocketConnection.prototype, 'connectionStatus').mockReturnValue({ statusCode: StatusCode.BAD, messages: ['WS DisConnected'], }) + expect(device.getStatus()).toEqual({ + statusCode: StatusCode.BAD, + messages: ['WS DisConnected'], + })🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@packages/timeline-state-resolver/src/integrations/websocketClient/__tests__/websocketClient.spec.ts` around lines 112 - 122, The test sets two different mocks for WebSocketConnection.prototype.connectionStatus and flips MockWebSocketConnection.prototype.isWsConnected but never asserts the resulting device status; after the first mock (StatusCode.GOOD / ['WS Connected']) add an assertion like expect(device.getStatus()).toEqual(...) to verify the GOOD/messages branch, then after toggling isWsConnected and setting the second mock (StatusCode.BAD / ['WS DisConnected']) add another expect(device.getStatus()).toEqual(...) to verify the BAD/messages branch and status transition; locate these changes around the mocked WebSocketConnection.prototype.connectionStatus and MockWebSocketConnection.prototype.isWsConnected calls in the test file and assert using device.getStatus().
♻️ Duplicate comments (2)
packages/timeline-state-resolver/src/service/DeviceInstance.ts (1)
45-51:⚠️ Potential issue | 🟠 Major | ⚡ Quick winPreserve legacy feature detection: do not synthesize
statusDetailsfrommessages.The legacy branch currently fabricates
statusDetails, which prevents consumers from distinguishing legacy devices from structured-status devices.🔧 Proposed fix
// Old style device, with only messages return { statusCode: input.statusCode, messages: input.messages, - statusDetails: input.messages.map((message) => ({ message })), + statusDetails: undefined, active, }Based on learnings: In the DeviceStatus interface within timeline-state-resolver, treat errors as a feature-detection mechanism: errors: [] means structured errors are supported, while errors: undefined means structured errors are not supported and consumers should fall back to the plain text messages array.
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@packages/timeline-state-resolver/src/service/DeviceInstance.ts` around lines 45 - 51, The current legacy branch in DeviceInstance.ts is synthesizing statusDetails from messages which hides feature-detection; change the return so it does not fabricate statusDetails — only include statusDetails when the incoming input.statusDetails (or structured errors) is present; for the old-style path return { statusCode: input.statusCode, messages: input.messages, active } (leave statusDetails undefined/omitted) so consumers can detect legacy devices by errors/statusDetails being undefined.packages/timeline-state-resolver/src/integrations/hyperdeck/index.ts (1)
261-269:⚠️ Potential issue | 🟡 Minor | ⚡ Quick winUse runtime
deviceNamefor status context.Line 261 hardcodes
"Hyperdeck", so renamed instances emit misleading context in status details.🔧 Proposed fix
- const deviceName = 'Hyperdeck' + const deviceName = this.context.deviceName || 'Hyperdeck'🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@packages/timeline-state-resolver/src/integrations/hyperdeck/index.ts` around lines 261 - 269, The status detail uses a hardcoded const deviceName = 'Hyperdeck' which produces misleading context; replace the hardcoded value with the runtime device name when building the NOT_CONNECTED status (use the instance property or init option such as this.deviceName or this._initOptions?.deviceName if available) so createHyperdeckStatusDetail(HyperdeckStatusCode.NOT_CONNECTED, { deviceName, host: ..., port: ... }) receives the actual device name; update the declaration and any other usages of deviceName in this block to reference the runtime property instead of the literal.
🧹 Nitpick comments (1)
packages/timeline-state-resolver/src/integrations/tricaster/messages.ts (1)
9-15: 💤 Low valueConsider enhancing the documentation with usage examples.
The JSDoc comment accurately describes the function but is minimal. Adding a usage example would help developers understand how to use this helper, especially showing how the generic type parameter ensures type safety between the code and its context.
📝 Enhanced documentation example
/** * Type-safe helper for creating TriCaster device status details + * + * `@example` + * ```ts + * const detail = createTriCasterStatusDetail( + * TriCasterStatusCode.NOT_CONNECTED, + * { /* context for NOT_CONNECTED */ } + * ); + * // Returns: { code, context, message: "Rendered message..." } + * ``` */ export function createTriCasterStatusDetail<T extends TriCasterStatusCode>(🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@packages/timeline-state-resolver/src/integrations/tricaster/messages.ts` around lines 9 - 15, Add a short usage example to the JSDoc for createTriCasterStatusDetail showing how to call it with a TriCasterStatusCode and the matching context so readers see the type-safety in action; reference the generic T and the related types (TriCasterStatusCode, TriCasterStatusContextMap, TriCasterStatusDetail) in the example and include a small inline sample call and expected return shape to demonstrate that the code and context must match.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@packages/timeline-state-resolver/src/integrations/tricaster/messages.ts`:
- Around line 1-7: The import in messages.ts includes TriCasterStatusDetail
which doesn't exist in the timeline-state-resolver-types package; update the
import to match the actual exported type names or add the missing type to the
types package. Inspect the types file that defines TriCasterStatusCode,
TriCasterStatusContextMap, TriCasterStatusMessages, and
interpolateTemplateString in the 10.0.0-release53 branch, then either replace
TriCasterStatusDetail with the correct existing type name used there or add a
new export named TriCasterStatusDetail to
packages/timeline-state-resolver-types/src/integrations/tricaster.ts and
re-export it so messages.ts can import it alongside TriCasterStatusCode,
TriCasterStatusContextMap, TriCasterStatusMessages, and
interpolateTemplateString.
In `@packages/timeline-state-resolver/src/service/DeviceInstance.ts`:
- Line 30: Remove the trailing whitespace in the doc comment for the
DeviceStatus normalization comment (the comment starting "/** Normalise a
DeviceStatusInput (from device.getStatus()) to a full DeviceStatus.") in
DeviceInstance.ts so it complies with Prettier; update the comment text to have
no trailing spaces and close the JSDoc block correctly.
---
Outside diff comments:
In
`@packages/timeline-state-resolver/src/integrations/websocketClient/__tests__/websocketClient.spec.ts`:
- Around line 112-122: The test sets two different mocks for
WebSocketConnection.prototype.connectionStatus and flips
MockWebSocketConnection.prototype.isWsConnected but never asserts the resulting
device status; after the first mock (StatusCode.GOOD / ['WS Connected']) add an
assertion like expect(device.getStatus()).toEqual(...) to verify the
GOOD/messages branch, then after toggling isWsConnected and setting the second
mock (StatusCode.BAD / ['WS DisConnected']) add another
expect(device.getStatus()).toEqual(...) to verify the BAD/messages branch and
status transition; locate these changes around the mocked
WebSocketConnection.prototype.connectionStatus and
MockWebSocketConnection.prototype.isWsConnected calls in the test file and
assert using device.getStatus().
---
Duplicate comments:
In `@packages/timeline-state-resolver/src/integrations/hyperdeck/index.ts`:
- Around line 261-269: The status detail uses a hardcoded const deviceName =
'Hyperdeck' which produces misleading context; replace the hardcoded value with
the runtime device name when building the NOT_CONNECTED status (use the instance
property or init option such as this.deviceName or this._initOptions?.deviceName
if available) so createHyperdeckStatusDetail(HyperdeckStatusCode.NOT_CONNECTED,
{ deviceName, host: ..., port: ... }) receives the actual device name; update
the declaration and any other usages of deviceName in this block to reference
the runtime property instead of the literal.
In `@packages/timeline-state-resolver/src/service/DeviceInstance.ts`:
- Around line 45-51: The current legacy branch in DeviceInstance.ts is
synthesizing statusDetails from messages which hides feature-detection; change
the return so it does not fabricate statusDetails — only include statusDetails
when the incoming input.statusDetails (or structured errors) is present; for the
old-style path return { statusCode: input.statusCode, messages: input.messages,
active } (leave statusDetails undefined/omitted) so consumers can detect legacy
devices by errors/statusDetails being undefined.
---
Nitpick comments:
In `@packages/timeline-state-resolver/src/integrations/tricaster/messages.ts`:
- Around line 9-15: Add a short usage example to the JSDoc for
createTriCasterStatusDetail showing how to call it with a TriCasterStatusCode
and the matching context so readers see the type-safety in action; reference the
generic T and the related types (TriCasterStatusCode, TriCasterStatusContextMap,
TriCasterStatusDetail) in the example and include a small inline sample call and
expected return shape to demonstrate that the code and context must match.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro
Run ID: ec1ba018-8b57-40b8-9200-4d37584c7d86
⛔ Files ignored due to path filters (2)
packages/timeline-state-resolver-types/src/__tests__/__snapshots__/index.spec.ts.snapis excluded by!**/*.snappackages/timeline-state-resolver/src/__tests__/__snapshots__/index.spec.ts.snapis excluded by!**/*.snap
📒 Files selected for processing (75)
packages/timeline-state-resolver-types/src/index.tspackages/timeline-state-resolver-types/src/integrations/atem.tspackages/timeline-state-resolver-types/src/integrations/casparcg.tspackages/timeline-state-resolver-types/src/integrations/httpWatcher.tspackages/timeline-state-resolver-types/src/integrations/hyperdeck.tspackages/timeline-state-resolver-types/src/integrations/lawo.tspackages/timeline-state-resolver-types/src/integrations/obs.tspackages/timeline-state-resolver-types/src/integrations/osc.tspackages/timeline-state-resolver-types/src/integrations/panasonicPTZ.tspackages/timeline-state-resolver-types/src/integrations/pharos.tspackages/timeline-state-resolver-types/src/integrations/quantel.tspackages/timeline-state-resolver-types/src/integrations/shotoku.tspackages/timeline-state-resolver-types/src/integrations/sisyfos.tspackages/timeline-state-resolver-types/src/integrations/sofieChef.tspackages/timeline-state-resolver-types/src/integrations/telemetrics.tspackages/timeline-state-resolver-types/src/integrations/tricaster.tspackages/timeline-state-resolver-types/src/integrations/vizMSE.tspackages/timeline-state-resolver-types/src/integrations/vmix.tspackages/timeline-state-resolver-types/src/integrations/websocketClient.tspackages/timeline-state-resolver/src/devices/device.tspackages/timeline-state-resolver/src/integrations/__tests__/testlib.tspackages/timeline-state-resolver/src/integrations/abstract/index.tspackages/timeline-state-resolver/src/integrations/atem/__tests__/atem.spec.tspackages/timeline-state-resolver/src/integrations/atem/index.tspackages/timeline-state-resolver/src/integrations/atem/messages.tspackages/timeline-state-resolver/src/integrations/casparCG/index.tspackages/timeline-state-resolver/src/integrations/casparCG/messages.tspackages/timeline-state-resolver/src/integrations/httpSend/index.tspackages/timeline-state-resolver/src/integrations/httpWatcher/__tests__/httpwatcher.spec.tspackages/timeline-state-resolver/src/integrations/httpWatcher/index.tspackages/timeline-state-resolver/src/integrations/httpWatcher/messages.tspackages/timeline-state-resolver/src/integrations/hyperdeck/__tests__/hyperdeck.spec.tspackages/timeline-state-resolver/src/integrations/hyperdeck/index.tspackages/timeline-state-resolver/src/integrations/hyperdeck/messages.tspackages/timeline-state-resolver/src/integrations/kairos/index.tspackages/timeline-state-resolver/src/integrations/lawo/index.tspackages/timeline-state-resolver/src/integrations/lawo/messages.tspackages/timeline-state-resolver/src/integrations/multiOsc/index.tspackages/timeline-state-resolver/src/integrations/obs/index.tspackages/timeline-state-resolver/src/integrations/obs/messages.tspackages/timeline-state-resolver/src/integrations/ograf/index.tspackages/timeline-state-resolver/src/integrations/osc/index.tspackages/timeline-state-resolver/src/integrations/osc/messages.tspackages/timeline-state-resolver/src/integrations/panasonicPTZ/index.tspackages/timeline-state-resolver/src/integrations/panasonicPTZ/messages.tspackages/timeline-state-resolver/src/integrations/pharos/index.tspackages/timeline-state-resolver/src/integrations/pharos/messages.tspackages/timeline-state-resolver/src/integrations/quantel/index.tspackages/timeline-state-resolver/src/integrations/quantel/messages.tspackages/timeline-state-resolver/src/integrations/shotoku/index.tspackages/timeline-state-resolver/src/integrations/shotoku/messages.tspackages/timeline-state-resolver/src/integrations/singularLive/index.tspackages/timeline-state-resolver/src/integrations/sisyfos/index.tspackages/timeline-state-resolver/src/integrations/sisyfos/messages.tspackages/timeline-state-resolver/src/integrations/sofieChef/__tests__/sofieChef.spec.tspackages/timeline-state-resolver/src/integrations/sofieChef/index.tspackages/timeline-state-resolver/src/integrations/sofieChef/messages.tspackages/timeline-state-resolver/src/integrations/tcpSend/index.tspackages/timeline-state-resolver/src/integrations/telemetrics/__tests__/telemetrics.spec.tspackages/timeline-state-resolver/src/integrations/telemetrics/index.tspackages/timeline-state-resolver/src/integrations/telemetrics/messages.tspackages/timeline-state-resolver/src/integrations/tricaster/index.tspackages/timeline-state-resolver/src/integrations/tricaster/messages.tspackages/timeline-state-resolver/src/integrations/udpSend/index.tspackages/timeline-state-resolver/src/integrations/viscaOverIP/index.tspackages/timeline-state-resolver/src/integrations/vizMSE/index.tspackages/timeline-state-resolver/src/integrations/vizMSE/messages.tspackages/timeline-state-resolver/src/integrations/vmix/index.tspackages/timeline-state-resolver/src/integrations/vmix/messages.tspackages/timeline-state-resolver/src/integrations/websocketClient/__tests__/websocketClient.spec.tspackages/timeline-state-resolver/src/integrations/websocketClient/connection.tspackages/timeline-state-resolver/src/integrations/websocketClient/index.tspackages/timeline-state-resolver/src/integrations/websocketClient/messages.tspackages/timeline-state-resolver/src/service/DeviceInstance.tspackages/timeline-state-resolver/src/service/__tests__/deviceInstance.spec.ts
✅ Files skipped from review due to trivial changes (4)
- packages/timeline-state-resolver/src/service/tests/deviceInstance.spec.ts
- packages/timeline-state-resolver/src/integrations/kairos/index.ts
- packages/timeline-state-resolver-types/src/integrations/websocketClient.ts
- packages/timeline-state-resolver-types/src/integrations/casparcg.ts
🚧 Files skipped from review as they are similar to previous changes (61)
- packages/timeline-state-resolver/src/integrations/sisyfos/messages.ts
- packages/timeline-state-resolver/src/integrations/pharos/messages.ts
- packages/timeline-state-resolver/src/integrations/udpSend/index.ts
- packages/timeline-state-resolver/src/integrations/sofieChef/tests/sofieChef.spec.ts
- packages/timeline-state-resolver/src/integrations/atem/messages.ts
- packages/timeline-state-resolver/src/integrations/panasonicPTZ/messages.ts
- packages/timeline-state-resolver/src/integrations/abstract/index.ts
- packages/timeline-state-resolver-types/src/integrations/hyperdeck.ts
- packages/timeline-state-resolver/src/integrations/ograf/index.ts
- packages/timeline-state-resolver/src/devices/device.ts
- packages/timeline-state-resolver/src/integrations/obs/messages.ts
- packages/timeline-state-resolver/src/integrations/osc/messages.ts
- packages/timeline-state-resolver/src/integrations/vizMSE/messages.ts
- packages/timeline-state-resolver/src/integrations/quantel/index.ts
- packages/timeline-state-resolver/src/integrations/websocketClient/index.ts
- packages/timeline-state-resolver/src/integrations/shotoku/messages.ts
- packages/timeline-state-resolver/src/integrations/httpWatcher/messages.ts
- packages/timeline-state-resolver/src/integrations/quantel/messages.ts
- packages/timeline-state-resolver/src/integrations/httpSend/index.ts
- packages/timeline-state-resolver-types/src/integrations/vizMSE.ts
- packages/timeline-state-resolver-types/src/integrations/obs.ts
- packages/timeline-state-resolver-types/src/integrations/panasonicPTZ.ts
- packages/timeline-state-resolver/src/integrations/sofieChef/messages.ts
- packages/timeline-state-resolver-types/src/integrations/tricaster.ts
- packages/timeline-state-resolver/src/integrations/tricaster/index.ts
- packages/timeline-state-resolver/src/integrations/hyperdeck/messages.ts
- packages/timeline-state-resolver/src/integrations/vmix/messages.ts
- packages/timeline-state-resolver-types/src/integrations/osc.ts
- packages/timeline-state-resolver-types/src/integrations/lawo.ts
- packages/timeline-state-resolver/src/integrations/telemetrics/tests/telemetrics.spec.ts
- packages/timeline-state-resolver/src/integrations/obs/index.ts
- packages/timeline-state-resolver/src/integrations/websocketClient/messages.ts
- packages/timeline-state-resolver/src/integrations/vizMSE/index.ts
- packages/timeline-state-resolver-types/src/integrations/vmix.ts
- packages/timeline-state-resolver/src/integrations/sofieChef/index.ts
- packages/timeline-state-resolver/src/integrations/pharos/index.ts
- packages/timeline-state-resolver/src/integrations/httpWatcher/tests/httpwatcher.spec.ts
- packages/timeline-state-resolver/src/integrations/vmix/index.ts
- packages/timeline-state-resolver/src/integrations/singularLive/index.ts
- packages/timeline-state-resolver/src/integrations/shotoku/index.ts
- packages/timeline-state-resolver/src/integrations/telemetrics/messages.ts
- packages/timeline-state-resolver/src/integrations/casparCG/index.ts
- packages/timeline-state-resolver/src/integrations/lawo/index.ts
- packages/timeline-state-resolver/src/integrations/atem/tests/atem.spec.ts
- packages/timeline-state-resolver/src/integrations/viscaOverIP/index.ts
- packages/timeline-state-resolver/src/integrations/hyperdeck/tests/hyperdeck.spec.ts
- packages/timeline-state-resolver-types/src/integrations/httpWatcher.ts
- packages/timeline-state-resolver-types/src/integrations/sisyfos.ts
- packages/timeline-state-resolver/src/integrations/sisyfos/index.ts
- packages/timeline-state-resolver/src/integrations/osc/index.ts
- packages/timeline-state-resolver/src/integrations/httpWatcher/index.ts
- packages/timeline-state-resolver/src/integrations/casparCG/messages.ts
- packages/timeline-state-resolver/src/integrations/telemetrics/index.ts
- packages/timeline-state-resolver-types/src/integrations/pharos.ts
- packages/timeline-state-resolver/src/integrations/panasonicPTZ/index.ts
- packages/timeline-state-resolver-types/src/integrations/atem.ts
- packages/timeline-state-resolver/src/integrations/atem/index.ts
- packages/timeline-state-resolver-types/src/integrations/shotoku.ts
- packages/timeline-state-resolver-types/src/integrations/telemetrics.ts
- packages/timeline-state-resolver/src/integrations/websocketClient/connection.ts
- packages/timeline-state-resolver-types/src/integrations/sofieChef.ts
Adds normaliseDeviceStatus() which converts the DeviceStatusInput union (legacy messages[] or new statusDetails[]) into a full DeviceStatus with both fields populated. Conversion is applied at the two points where status crosses into the conductor: DeviceInstance.getStatus() and the connectionChanged handler in the device context API. The abstract device base class and DeviceInstance are updated to reflect the DeviceStatusInput return type from device implementations.
Updates getStatus() return type from Omit<DeviceStatus, 'active'> to DeviceStatusInput for kairos, multiOsc, singularLive, tcpSend, udpSend, viscaOverIP, ograf and httpSend. Also adds deviceName to the shared test device context mock.
945a3c6 to
f8a8172
Compare
|
There was a problem hiding this comment.
🧹 Nitpick comments (1)
packages/timeline-state-resolver/src/integrations/vmix/messages.ts (1)
4-13: 💤 Low valueConsider showing diverse context examples.
Both examples use identical context structures. If different
VMixStatusCodevalues require different context shapes (as enforced byVMixStatusContextMap[T]), showing examples with varying contexts would better demonstrate the type-safety benefit.🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@packages/timeline-state-resolver/src/integrations/vmix/messages.ts` around lines 4 - 13, Update the JSDoc examples for createVMixStatusDetail to show different context shapes tied to different VMixStatusCode values so readers see the type-safety in action: add at least one example using a status whose context differs from { deviceName, host } (reference VMixStatusCode and VMixStatusContextMap) — e.g., an example for a code that requires an error or reason field and one for a code that requires additional fields — and ensure the examples call createVMixStatusDetail with the correct context shape for each VMixStatusCode to illustrate compile-time enforcement.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Nitpick comments:
In `@packages/timeline-state-resolver/src/integrations/vmix/messages.ts`:
- Around line 4-13: Update the JSDoc examples for createVMixStatusDetail to show
different context shapes tied to different VMixStatusCode values so readers see
the type-safety in action: add at least one example using a status whose context
differs from { deviceName, host } (reference VMixStatusCode and
VMixStatusContextMap) — e.g., an example for a code that requires an error or
reason field and one for a code that requires additional fields — and ensure the
examples call createVMixStatusDetail with the correct context shape for each
VMixStatusCode to illustrate compile-time enforcement.
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro
Run ID: 35399cff-0f87-4500-97e0-506c809f432d
⛔ Files ignored due to path filters (2)
packages/timeline-state-resolver-types/src/__tests__/__snapshots__/index.spec.ts.snapis excluded by!**/*.snappackages/timeline-state-resolver/src/__tests__/__snapshots__/index.spec.ts.snapis excluded by!**/*.snap
📒 Files selected for processing (75)
packages/timeline-state-resolver-types/src/index.tspackages/timeline-state-resolver-types/src/integrations/atem.tspackages/timeline-state-resolver-types/src/integrations/casparcg.tspackages/timeline-state-resolver-types/src/integrations/httpWatcher.tspackages/timeline-state-resolver-types/src/integrations/hyperdeck.tspackages/timeline-state-resolver-types/src/integrations/lawo.tspackages/timeline-state-resolver-types/src/integrations/obs.tspackages/timeline-state-resolver-types/src/integrations/osc.tspackages/timeline-state-resolver-types/src/integrations/panasonicPTZ.tspackages/timeline-state-resolver-types/src/integrations/pharos.tspackages/timeline-state-resolver-types/src/integrations/quantel.tspackages/timeline-state-resolver-types/src/integrations/shotoku.tspackages/timeline-state-resolver-types/src/integrations/sisyfos.tspackages/timeline-state-resolver-types/src/integrations/sofieChef.tspackages/timeline-state-resolver-types/src/integrations/telemetrics.tspackages/timeline-state-resolver-types/src/integrations/tricaster.tspackages/timeline-state-resolver-types/src/integrations/vizMSE.tspackages/timeline-state-resolver-types/src/integrations/vmix.tspackages/timeline-state-resolver-types/src/integrations/websocketClient.tspackages/timeline-state-resolver/src/devices/device.tspackages/timeline-state-resolver/src/integrations/__tests__/testlib.tspackages/timeline-state-resolver/src/integrations/abstract/index.tspackages/timeline-state-resolver/src/integrations/atem/__tests__/atem.spec.tspackages/timeline-state-resolver/src/integrations/atem/index.tspackages/timeline-state-resolver/src/integrations/atem/messages.tspackages/timeline-state-resolver/src/integrations/casparCG/index.tspackages/timeline-state-resolver/src/integrations/casparCG/messages.tspackages/timeline-state-resolver/src/integrations/httpSend/index.tspackages/timeline-state-resolver/src/integrations/httpWatcher/__tests__/httpwatcher.spec.tspackages/timeline-state-resolver/src/integrations/httpWatcher/index.tspackages/timeline-state-resolver/src/integrations/httpWatcher/messages.tspackages/timeline-state-resolver/src/integrations/hyperdeck/__tests__/hyperdeck.spec.tspackages/timeline-state-resolver/src/integrations/hyperdeck/index.tspackages/timeline-state-resolver/src/integrations/hyperdeck/messages.tspackages/timeline-state-resolver/src/integrations/kairos/index.tspackages/timeline-state-resolver/src/integrations/lawo/index.tspackages/timeline-state-resolver/src/integrations/lawo/messages.tspackages/timeline-state-resolver/src/integrations/multiOsc/index.tspackages/timeline-state-resolver/src/integrations/obs/index.tspackages/timeline-state-resolver/src/integrations/obs/messages.tspackages/timeline-state-resolver/src/integrations/ograf/index.tspackages/timeline-state-resolver/src/integrations/osc/index.tspackages/timeline-state-resolver/src/integrations/osc/messages.tspackages/timeline-state-resolver/src/integrations/panasonicPTZ/index.tspackages/timeline-state-resolver/src/integrations/panasonicPTZ/messages.tspackages/timeline-state-resolver/src/integrations/pharos/index.tspackages/timeline-state-resolver/src/integrations/pharos/messages.tspackages/timeline-state-resolver/src/integrations/quantel/index.tspackages/timeline-state-resolver/src/integrations/quantel/messages.tspackages/timeline-state-resolver/src/integrations/shotoku/index.tspackages/timeline-state-resolver/src/integrations/shotoku/messages.tspackages/timeline-state-resolver/src/integrations/singularLive/index.tspackages/timeline-state-resolver/src/integrations/sisyfos/index.tspackages/timeline-state-resolver/src/integrations/sisyfos/messages.tspackages/timeline-state-resolver/src/integrations/sofieChef/__tests__/sofieChef.spec.tspackages/timeline-state-resolver/src/integrations/sofieChef/index.tspackages/timeline-state-resolver/src/integrations/sofieChef/messages.tspackages/timeline-state-resolver/src/integrations/tcpSend/index.tspackages/timeline-state-resolver/src/integrations/telemetrics/__tests__/telemetrics.spec.tspackages/timeline-state-resolver/src/integrations/telemetrics/index.tspackages/timeline-state-resolver/src/integrations/telemetrics/messages.tspackages/timeline-state-resolver/src/integrations/tricaster/index.tspackages/timeline-state-resolver/src/integrations/tricaster/messages.tspackages/timeline-state-resolver/src/integrations/udpSend/index.tspackages/timeline-state-resolver/src/integrations/viscaOverIP/index.tspackages/timeline-state-resolver/src/integrations/vizMSE/index.tspackages/timeline-state-resolver/src/integrations/vizMSE/messages.tspackages/timeline-state-resolver/src/integrations/vmix/index.tspackages/timeline-state-resolver/src/integrations/vmix/messages.tspackages/timeline-state-resolver/src/integrations/websocketClient/__tests__/websocketClient.spec.tspackages/timeline-state-resolver/src/integrations/websocketClient/connection.tspackages/timeline-state-resolver/src/integrations/websocketClient/index.tspackages/timeline-state-resolver/src/integrations/websocketClient/messages.tspackages/timeline-state-resolver/src/service/DeviceInstance.tspackages/timeline-state-resolver/src/service/__tests__/deviceInstance.spec.ts
✅ Files skipped from review due to trivial changes (10)
- packages/timeline-state-resolver/src/integrations/telemetrics/tests/telemetrics.spec.ts
- packages/timeline-state-resolver/src/integrations/udpSend/index.ts
- packages/timeline-state-resolver/src/integrations/httpSend/index.ts
- packages/timeline-state-resolver/src/integrations/ograf/index.ts
- packages/timeline-state-resolver/src/devices/device.ts
- packages/timeline-state-resolver/src/integrations/sofieChef/tests/sofieChef.spec.ts
- packages/timeline-state-resolver/src/integrations/websocketClient/tests/websocketClient.spec.ts
- packages/timeline-state-resolver/src/integrations/singularLive/index.ts
- packages/timeline-state-resolver/src/integrations/viscaOverIP/index.ts
- packages/timeline-state-resolver/src/service/tests/deviceInstance.spec.ts
🚧 Files skipped from review as they are similar to previous changes (62)
- packages/timeline-state-resolver/src/integrations/multiOsc/index.ts
- packages/timeline-state-resolver/src/integrations/vizMSE/messages.ts
- packages/timeline-state-resolver/src/integrations/osc/index.ts
- packages/timeline-state-resolver/src/integrations/atem/messages.ts
- packages/timeline-state-resolver/src/integrations/quantel/messages.ts
- packages/timeline-state-resolver/src/integrations/shotoku/messages.ts
- packages/timeline-state-resolver/src/integrations/sisyfos/messages.ts
- packages/timeline-state-resolver/src/integrations/hyperdeck/messages.ts
- packages/timeline-state-resolver/src/integrations/websocketClient/messages.ts
- packages/timeline-state-resolver/src/integrations/sofieChef/index.ts
- packages/timeline-state-resolver/src/integrations/tests/testlib.ts
- packages/timeline-state-resolver/src/integrations/abstract/index.ts
- packages/timeline-state-resolver-types/src/integrations/hyperdeck.ts
- packages/timeline-state-resolver/src/integrations/obs/messages.ts
- packages/timeline-state-resolver/src/integrations/osc/messages.ts
- packages/timeline-state-resolver/src/integrations/httpWatcher/index.ts
- packages/timeline-state-resolver-types/src/integrations/casparcg.ts
- packages/timeline-state-resolver-types/src/integrations/quantel.ts
- packages/timeline-state-resolver-types/src/integrations/pharos.ts
- packages/timeline-state-resolver-types/src/integrations/websocketClient.ts
- packages/timeline-state-resolver-types/src/integrations/sofieChef.ts
- packages/timeline-state-resolver-types/src/index.ts
- packages/timeline-state-resolver-types/src/integrations/atem.ts
- packages/timeline-state-resolver/src/integrations/sisyfos/index.ts
- packages/timeline-state-resolver-types/src/integrations/vizMSE.ts
- packages/timeline-state-resolver-types/src/integrations/sisyfos.ts
- packages/timeline-state-resolver/src/service/DeviceInstance.ts
- packages/timeline-state-resolver/src/integrations/lawo/index.ts
- packages/timeline-state-resolver/src/integrations/kairos/index.ts
- packages/timeline-state-resolver/src/integrations/telemetrics/messages.ts
- packages/timeline-state-resolver/src/integrations/atem/index.ts
- packages/timeline-state-resolver/src/integrations/websocketClient/index.ts
- packages/timeline-state-resolver/src/integrations/tricaster/messages.ts
- packages/timeline-state-resolver/src/integrations/telemetrics/index.ts
- packages/timeline-state-resolver-types/src/integrations/tricaster.ts
- packages/timeline-state-resolver/src/integrations/httpWatcher/tests/httpwatcher.spec.ts
- packages/timeline-state-resolver/src/integrations/lawo/messages.ts
- packages/timeline-state-resolver/src/integrations/panasonicPTZ/messages.ts
- packages/timeline-state-resolver-types/src/integrations/shotoku.ts
- packages/timeline-state-resolver-types/src/integrations/httpWatcher.ts
- packages/timeline-state-resolver/src/integrations/obs/index.ts
- packages/timeline-state-resolver/src/integrations/httpWatcher/messages.ts
- packages/timeline-state-resolver/src/integrations/shotoku/index.ts
- packages/timeline-state-resolver/src/integrations/pharos/messages.ts
- packages/timeline-state-resolver-types/src/integrations/vmix.ts
- packages/timeline-state-resolver-types/src/integrations/telemetrics.ts
- packages/timeline-state-resolver-types/src/integrations/obs.ts
- packages/timeline-state-resolver/src/integrations/casparCG/index.ts
- packages/timeline-state-resolver-types/src/integrations/panasonicPTZ.ts
- packages/timeline-state-resolver/src/integrations/casparCG/messages.ts
- packages/timeline-state-resolver/src/integrations/sofieChef/messages.ts
- packages/timeline-state-resolver-types/src/integrations/lawo.ts
- packages/timeline-state-resolver/src/integrations/atem/tests/atem.spec.ts
- packages/timeline-state-resolver/src/integrations/quantel/index.ts
- packages/timeline-state-resolver/src/integrations/pharos/index.ts
- packages/timeline-state-resolver/src/integrations/panasonicPTZ/index.ts
- packages/timeline-state-resolver-types/src/integrations/osc.ts
- packages/timeline-state-resolver/src/integrations/vizMSE/index.ts
- packages/timeline-state-resolver/src/integrations/hyperdeck/tests/hyperdeck.spec.ts
- packages/timeline-state-resolver/src/integrations/tricaster/index.ts
- packages/timeline-state-resolver/src/integrations/vmix/index.ts
- packages/timeline-state-resolver/src/integrations/websocketClient/connection.ts



About the Contributor
This pull request is posted on behalf of the BBC.
Type of Contribution
This is a Feature.
Current Behavior
Errors are reported as plain strings. This makes them hard to understand in an machine readable way by e.g. sofie blueprints or translate.
New Behavior
Errors will include error codes and context as well as the message for backwards compatibility.
Testing Instructions
Other Information
Status