mirror of
https://github.com/keymanapp/keyman.git
synced 2026-10-30 17:57:57 +00:00
kmc already reported unhandled exceptions, but any handled fatal errors
were captured and only reported to the user. It is better to report
these to Sentry as these are still unexpected.
I have refactored all the fatal exception messages in various kmc
modules to use a common mechanism, keeping all the Sentry integration in
kmc, now passing exception data up in the `CompilerEvent.exceptionVar`
property.
* I took the opportunity to rename messages.ts to
infrastructureMessages.ts
* @types/chai was missing which gave intellisense errors in vscode
* normal exit of kmc now provides an opportunity for error reports to
Sentry to be finalized
* Added a unit test for fatal errors in kmc
* Added a manual test pathway with `SENTRY_CLIENT_TEST_BUILD_EXCEPTION`
env var to trip the build fatal error mechanism and verify that it
looks ok; the following shows test runs demonstrate how fatal build
errors are reported:
```
mcdurdin@THARK MINGW64 /c/Projects/keyman/app/developer/src/kmc (chore/developer/report-fatal-compiler-errors-to-sentry)
$ SENTRY_CLIENT_TEST_BUILD_EXCEPTION=1 node . --error-reporting build
fatal KM05001: Unexpected exception: Error: Test exception from SENTRY_CLIENT_TEST_BUILD_EXCEPTION
Call stack:
Error: Test exception from SENTRY_CLIENT_TEST_BUILD_EXCEPTION
at build (file:///C:/Projects/keyman/app/developer/src/kmc/build/src/commands/build.js:78:19)
at Command.<anonymous> (file:///C:/Projects/keyman/app/developer/src/kmc/build/src/commands/build.js:66:24)
at Command.listener [as _actionHandler] (C:\Projects\keyman\app\node_modules\commander\lib\command.js:482:17)
at C:\Projects\keyman\app\node_modules\commander\lib\command.js:1283:65
at Command._chainOrCall (C:\Projects\keyman\app\node_modules\commander\lib\command.js:1177:12)
at Command._parseCommand (C:\Projects\keyman\app\node_modules\commander\lib\command.js:1283:27)
at C:\Projects\keyman\app\node_modules\commander\lib\command.js:1081:27
at Command._chainOrCall (C:\Projects\keyman\app\node_modules\commander\lib\command.js:1177:12)
at Command._dispatchSubcommand (C:\Projects\keyman\app\node_modules\commander\lib\command.js:1077:23)
at Command._parseCommand (C:\Projects\keyman\app\node_modules\commander\lib\command.js:1248:19)
This error has been automatically reported to the Keyman team.
Identifier: 6f0fca1a26694c22b03f02b2463d39c5
Application: Keyman Developer
Reported at: https://sentry.io/organizations/keyman/projects/keyman-developer/events/6f0fca1a26694c22b03f02b2463d39c5/
mcdurdin@THARK MINGW64 /c/Projects/keyman/app/developer/src/kmc (chore/developer/report-fatal-compiler-errors-to-sentry)
$ SENTRY_CLIENT_TEST_BUILD_EXCEPTION=1 node . --no-error-reporting build
fatal KM05001: Unexpected exception: Error: Test exception from SENTRY_CLIENT_TEST_BUILD_EXCEPTION
Call stack:
Error: Test exception from SENTRY_CLIENT_TEST_BUILD_EXCEPTION
at build (file:///C:/Projects/keyman/app/developer/src/kmc/build/src/commands/build.js:78:19)
at Command.<anonymous> (file:///C:/Projects/keyman/app/developer/src/kmc/build/src/commands/build.js:66:24)
at Command.listener [as _actionHandler] (C:\Projects\keyman\app\node_modules\commander\lib\command.js:482:17)
at C:\Projects\keyman\app\node_modules\commander\lib\command.js:1283:65
at Command._chainOrCall (C:\Projects\keyman\app\node_modules\commander\lib\command.js:1177:12)
at Command._parseCommand (C:\Projects\keyman\app\node_modules\commander\lib\command.js:1283:27)
at C:\Projects\keyman\app\node_modules\commander\lib\command.js:1081:27
at Command._chainOrCall (C:\Projects\keyman\app\node_modules\commander\lib\command.js:1177:12)
at Command._dispatchSubcommand (C:\Projects\keyman\app\node_modules\commander\lib\command.js:1077:23)
at Command._parseCommand (C:\Projects\keyman\app\node_modules\commander\lib\command.js:1248:19)
```
68 lines
3.1 KiB
TypeScript
68 lines
3.1 KiB
TypeScript
import 'mocha';
|
|
import { assert } from 'chai';
|
|
import { InfrastructureMessages } from '../src/messages/infrastructureMessages.js';
|
|
import { verifyCompilerMessagesObject } from '@keymanapp/developer-test-helpers';
|
|
import { makePathToFixture } from './helpers/index.js';
|
|
import { NodeCompilerCallbacks } from '../src/util/NodeCompilerCallbacks.js';
|
|
import { CompilerErrorNamespace } from '@keymanapp/common-types';
|
|
import { unitTestEndpoints } from '../src/commands/build.js';
|
|
|
|
describe('InfrastructureMessages', function () {
|
|
it('should have a valid InfrastructureMessages object', function() {
|
|
return verifyCompilerMessagesObject(InfrastructureMessages, CompilerErrorNamespace.Infrastructure);
|
|
});
|
|
|
|
//
|
|
// Message tests
|
|
//
|
|
|
|
// FATAL_UnexpectedException
|
|
|
|
it('should generate FATAL_UnexpectedException if an exception is raised', async function() {
|
|
const ncb = new NodeCompilerCallbacks({logLevel: 'silent'});
|
|
process.env.SENTRY_CLIENT_TEST_BUILD_EXCEPTION = '1';
|
|
await unitTestEndpoints.build(null, ncb, {});
|
|
delete process.env.SENTRY_CLIENT_TEST_BUILD_EXCEPTION;
|
|
assert.isTrue(ncb.hasMessage(InfrastructureMessages.FATAL_UnexpectedException),
|
|
`FATAL_UnexpectedException not generated, instead got: `+JSON.stringify(ncb.messages,null,2));
|
|
assert.lengthOf(ncb.messages, 1);
|
|
assert.instanceOf<Error>(ncb.messages[0].exceptionVar, Error);
|
|
});
|
|
|
|
/*
|
|
// ERROR_FileDoesNotExist
|
|
|
|
it('should generate ERROR_FileDoesNotExist if a file does not exist', async function() {
|
|
await testForMessage(this, ['invalid-keyboards', 'error_file_does_not_exist.kmn'], CompilerMessages.ERROR_FileDoesNotExist);
|
|
});
|
|
|
|
// ERROR_FileTypeNotRecognized
|
|
|
|
it('should generate ERROR_FileTypeNotRecognized if a file is not a recognized type', async function() {
|
|
await testForMessage(this, ['invalid-keyboards', 'error_file_type_not_recognized.xxx'], CompilerMessages.ERROR_FileTypeNotRecognized);
|
|
});
|
|
|
|
// ERROR_OutFileNotValidForProjects
|
|
|
|
it('should generate ERROR_OutFileNotValidForProjects if an output file is specified for a project build', async function() {
|
|
await testForMessage(this, ['invalid-keyboards', 'error_out_file_not_valid_for_projects.kpj'], CompilerMessages.ERROR_OutFileNotValidForProjects);
|
|
});
|
|
|
|
// ERROR_InvalidProjectFile
|
|
|
|
it('should generate ERROR_InvalidProjectFile if a project file is invalid', async function() {
|
|
await testForMessage(this, ['invalid-keyboards', 'error_invalid_project_file.kpj'], CompilerMessages.ERROR_InvalidProjectFile);
|
|
});
|
|
*/
|
|
|
|
// HINT_FilenameHasDifferingCase
|
|
|
|
it('should generate HINT_FilenameHasDifferingCase if a referenced file has differing case', async function() {
|
|
// This message is generated by NodeCompilerCallbacks, because that's where the filesystem is visible,
|
|
// so we can't use our usual testForMessage pattern.
|
|
const ncb = new NodeCompilerCallbacks({logLevel: 'silent'});
|
|
ncb.loadFile(makePathToFixture('invalid-keyboards', 'Hint_Filename_Has_Differing_Case.kmn'));
|
|
assert.isTrue(ncb.hasMessage(InfrastructureMessages.HINT_FilenameHasDifferingCase),
|
|
`HINT_FilenameHasDifferingCase not generated, instead got: `+JSON.stringify(ncb.messages,null,2));
|
|
});
|
|
});
|