Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Association decorators should not show error notifications #2165

Merged
merged 18 commits into from
Nov 11, 2024

Conversation

hudson-newey
Copy link
Member

@hudson-newey hudson-newey commented Nov 7, 2024

Association decorators should not show error notifications

This pull request creates a new association injector that can be used to inject different options into the baw-api.service.ts

Changes

  • Adds an association-injector.service. This injector used in the abstract model constructor
  • Adds injectable BawAptOptions to the baw-api.service
  • Fixes a bug where the associations would throw errors (e.g. the audio recording list page if not logged in)
  • Fixes some minor formatting issues
  • Corrects TypeScript typing for ServiceToken.kind
  • Improves the TypeScript typing of ServiceProviders and AbstractDataModel
  • Add missing PageInfo tests to annotation search page

Issues

Fixes: #1967

Final Checklist

  • Assign reviewers if you have permission
  • Assign labels if you have permission
  • Link issues related to PR
  • Ensure project linter is not producing any warnings (npm run lint)
  • Ensure build is passing on all browsers (npm run test:all)
  • Ensure CI build is passing
  • Ensure docker container is passing (docs)

@hudson-newey hudson-newey added bug Something isn't working architecture Architectural changes to the software triage:medium Medium priority issue or pull request labels Nov 7, 2024
@hudson-newey hudson-newey self-assigned this Nov 7, 2024
@hudson-newey hudson-newey force-pushed the suppress-association-errors branch from 2a827ec to 7a17d7e Compare November 7, 2024 01:36
Copy link
Contributor

github-actions bot commented Nov 7, 2024

Size Change: +580 B (+0.02%)

Total Size: 3.59 MB

Filename Size Change
dist/workbench-client/browser/index.html 4.79 kB +2 B (+0.04%)
dist/workbench-client/browser/main-2BSDE7KO.js 0 B -1.13 MB (removed) 🏆
dist/workbench-client/server/main.js 1.94 MB +326 B (+0.02%)
dist/workbench-client/browser/main-SHI5ZZQN.js 1.13 MB +1.13 MB (new file) 🆕
ℹ️ View Unchanged
Filename Size
dist/workbench-client/browser/@ecoacoustics/web-components/_commonjsHelpers-BVfed4GL.js 432 B
dist/workbench-client/browser/@ecoacoustics/web-components/abstractComponent-gI12hGSz.js 6.49 kB
dist/workbench-client/browser/@ecoacoustics/web-components/assets/buffer-builder-processor-BhnxGUx8.js 1.16 kB
dist/workbench-client/browser/@ecoacoustics/web-components/assets/high-accuracy-time-processor-BevUJNwo.js 354 B
dist/workbench-client/browser/@ecoacoustics/web-components/attributes-DayhhJl-.js 313 B
dist/workbench-client/browser/@ecoacoustics/web-components/class-map-BJ2wQJjp.js 675 B
dist/workbench-client/browser/@ecoacoustics/web-components/classification-syqJf8YO.js 125 B
dist/workbench-client/browser/@ecoacoustics/web-components/colors-DMCqRncD.js 328 B
dist/workbench-client/browser/@ecoacoustics/web-components/components.js 116 kB
dist/workbench-client/browser/@ecoacoustics/web-components/components/axes.js 3.19 kB
dist/workbench-client/browser/@ecoacoustics/web-components/components/classification.js 1.77 kB
dist/workbench-client/browser/@ecoacoustics/web-components/components/data-source.js 63.3 kB
dist/workbench-client/browser/@ecoacoustics/web-components/components/decision.js 1.25 kB
dist/workbench-client/browser/@ecoacoustics/web-components/components/help-dialog.js 2.61 kB
dist/workbench-client/browser/@ecoacoustics/web-components/components/helpers/constants/contextTokens.js 209 B
dist/workbench-client/browser/@ecoacoustics/web-components/components/indicator.js 1.12 kB
dist/workbench-client/browser/@ecoacoustics/web-components/components/info-card.js 1.59 kB
dist/workbench-client/browser/@ecoacoustics/web-components/components/logger.js 418 B
dist/workbench-client/browser/@ecoacoustics/web-components/components/media-controls.js 38.2 kB
dist/workbench-client/browser/@ecoacoustics/web-components/components/progress-bar.js 1.13 kB
dist/workbench-client/browser/@ecoacoustics/web-components/components/spectrogram.js 167 kB
dist/workbench-client/browser/@ecoacoustics/web-components/components/verification-grid-settings.js 1.48 kB
dist/workbench-client/browser/@ecoacoustics/web-components/components/verification-grid-tile.js 3.55 kB
dist/workbench-client/browser/@ecoacoustics/web-components/components/verification-grid.js 387 B
dist/workbench-client/browser/@ecoacoustics/web-components/components/verification.js 1.3 kB
dist/workbench-client/browser/@ecoacoustics/web-components/consume-D2RSb1qY.js 614 B
dist/workbench-client/browser/@ecoacoustics/web-components/context-request-event-Bc4uem__.js 239 B
dist/workbench-client/browser/@ecoacoustics/web-components/custom-elements.json 9.59 kB
dist/workbench-client/browser/@ecoacoustics/web-components/decision-Btskh9bB.js 202 B
dist/workbench-client/browser/@ecoacoustics/web-components/decisionColors-DNuXUVq4.js 3.84 kB
dist/workbench-client/browser/@ecoacoustics/web-components/decorators-zsXcIcN9.js 516 B
dist/workbench-client/browser/@ecoacoustics/web-components/directive-B76A7YXI.js 343 B
dist/workbench-client/browser/@ecoacoustics/web-components/directive-helpers-DAca9yBy.js 638 B
dist/workbench-client/browser/@ecoacoustics/web-components/if-defined-YSzpD1Zv.js 178 B
dist/workbench-client/browser/@ecoacoustics/web-components/keyboard-MZyub3T-.js 117 B
dist/workbench-client/browser/@ecoacoustics/web-components/lit-element-CNpxFSzF.js 6.77 kB
dist/workbench-client/browser/@ecoacoustics/web-components/map-D8heArFD.js 184 B
dist/workbench-client/browser/@ecoacoustics/web-components/property-cctOu2Be.js 639 B
dist/workbench-client/browser/@ecoacoustics/web-components/provide-Ce8Vz0mw.js 1.18 kB
dist/workbench-client/browser/@ecoacoustics/web-components/query-sbFTBDPt.js 340 B
dist/workbench-client/browser/@ecoacoustics/web-components/signal-watcher-CbQ3umdl.js 377 B
dist/workbench-client/browser/@ecoacoustics/web-components/signals-core.module-BUxpRF5s.js 1.59 kB
dist/workbench-client/browser/@ecoacoustics/web-components/state-DJrhCpxL.js 203 B
dist/workbench-client/browser/@ecoacoustics/web-components/userAgent-CdrtNGdV.js 1.04 kB
dist/workbench-client/browser/@ecoacoustics/web-components/utilities-C38J31_r.js 432 B
dist/workbench-client/browser/@ecoacoustics/web-components/verification-grid-DnTXiJ40.js 12.1 kB
dist/workbench-client/browser/@ecoacoustics/web-components/watch-BnoWuiCc.js 1.02 kB
dist/workbench-client/browser/@ecoacoustics/web-components/when-CDK1Tt5Y.js 168 B
dist/workbench-client/browser/assets/environment.json 555 B
dist/workbench-client/browser/assets/test-assets/index.html 21 B
dist/workbench-client/browser/manifest.json 147 B
dist/workbench-client/browser/polyfills-C5CKP5CH.js 12.4 kB
dist/workbench-client/browser/styles-ETV6J7SM.css 39.6 kB
dist/workbench-client/server/952.js 4.21 kB

compressed-size-action

Copy link
Contributor

github-actions bot commented Nov 7, 2024

Unit Test Results

         4 files           4 suites   7m 42s ⏱️
16 052 tests 15 644 ✔️ 408 💤 0
16 200 runs  15 792 ✔️ 408 💤 0

Results for commit 615fa3b.

♻️ This comment has been updated with latest results.

@hudson-newey hudson-newey requested a review from atruskie November 7, 2024 05:38
// we use a different injector for associations so that the the we can
// inject the correct options for the baw-api service without affecting
// the options for the rest of the application
const injector: Injector = parent["injector"];
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

can we type check or guard (on name?) this somehow?

Copy link
Member Author

@hudson-newey hudson-newey Nov 8, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We can acomplish compile time type-checking with some fancy TypeScript branded types

image

We can't directly check the name property because injector types are broadened during compile time to Injector (losing name information)

The name property is also removed during runtime

Edit: This was definately the correct call. I found so many bugs when I changed the TS type

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Related commit

7920913

src/app/services/baw-api/ServiceTokens.ts Outdated Show resolved Hide resolved
src/app/services/baw-api/baw-api.module.ts Outdated Show resolved Hide resolved
@Inject(CACHE_SETTINGS) private cacheSettings: CacheSettings
@Inject(CACHE_SETTINGS) private cacheSettings: CacheSettings,
@Inject(ASSOCIATION_INJECTOR.token) protected associationInjector: any,
@Optional() @Inject(BAW_SERVICE_OPTIONS) private options: BawServiceOptions
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ok, flatten options with default in the ctor and store the merged result

  • default options: static and frozen
  • instance options: Object.assign({}, defaultOptions, options)
  • and ideally options that are set instance wide are not configurable in the methods

Now that we have configurable services, do we need the options configurable from individual methods? Where is disableNotificaitons used elsewhere?

Copy link
Member Author

@hudson-newey hudson-newey Nov 8, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

disableNotification is used in the security.service when we try to get the currently logged in user through a GET request.
Obviously in this case, we don't want to raise an error to the user if the user is not logged in, causing fetching the current user to fail.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

if that's the only other case, could we provide a service configured in the correct way and remove the method overload?

Copy link
Member Author

@hudson-newey hudson-newey Nov 11, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Associated issue: #2166

src/app/services/baw-api/baw-api.service.ts Outdated Show resolved Hide resolved
src/app/test/matchers/injectables.ts Show resolved Hide resolved
src/app/test/matchers/injectables.ts Outdated Show resolved Hide resolved
src/app/test/matchers/injectables.ts Outdated Show resolved Hide resolved
@hudson-newey hudson-newey marked this pull request as ready for review November 8, 2024 00:26
@hudson-newey hudson-newey requested a review from atruskie November 8, 2024 04:30
@@ -51,7 +53,7 @@ class AnnotationSearchComponent
protected config: NgbPaginationConfig,
protected modals: NgbModal,
protected annotationService: AnnotationService,
private injector: Injector
@Inject(ASSOCIATION_INJECTOR) private injector: AssociationInjector
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ok this is a bit of a smell. the only place the association injector should be needed is from services that create models.

we should also be injecting this injector in creation of whatever is using it - the search parameters

Copy link
Member Author

@hudson-newey hudson-newey Nov 11, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Related issue: #2167

@@ -75,7 +77,7 @@ class VerificationComponent
private route: ActivatedRoute,
private router: Router,
private location: Location,
private injector: Injector
@Inject(ASSOCIATION_INJECTOR) private injector: AssociationInjector
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ditto here

@@ -146,7 +148,9 @@ export class FolderRowComponent {
return this.harvestItem.report;
}

public constructor(private injector: Injector) {}
public constructor(
@Inject(ASSOCIATION_INJECTOR) protected injector: AssociationInjector,
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ditto

@@ -95,7 +97,7 @@ class PermissionsComponent
private permissionsApi: PermissionsService,
private accountsApi: AccountsService,
private route: ActivatedRoute,
private injector: Injector
@Inject(ASSOCIATION_INJECTOR) private injector: AssociationInjector,
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ditto

IParameterModel<EventSummaryReport>
{
public constructor(
queryStringParameters: Params = {},
public injector?: Injector
public injector?: AssociationInjector
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ditto


// this brand symbol should never be used at runtime
// it is only used to have a type that cannot be instantiated by TypeScript
// outside of the Brand function
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

and the purpose of this is?

To create something like a type alias that is not-equivalent as far as TS is concerned?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Discussed offline that this needed an inline code comment

image

import { Brand } from "@helpers/advancedTypes";
import { AbstractModel } from "./AbstractModel";

export type AssociationInjector = Brand<Injector, "AssociationInjector">;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this is very fancy, but I wonder if you couldn't have just subclassed injector?

I guess with brand there's no runtime difference

Copy link
Member Author

@hudson-newey hudson-newey Nov 11, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There are a couple of benefits to using a branded type

  1. There is no runtime difference (reducing the risk of bugs)
  2. Using a subclassed injector risks polymorphic type matching

e.g.

export class AssociationInjector extends Injector {}

console.log(AssociationInjector === Injector);
//			^ will not throw a compile time error unless we add a branding property at compile time or run time
// 			  resulting in the same solution, just with an additional class that we have to maintain

@atruskie atruskie merged commit 8909001 into master Nov 11, 2024
21 checks passed
@atruskie atruskie deleted the suppress-association-errors branch November 11, 2024 05:54
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
architecture Architectural changes to the software bug Something isn't working triage:medium Medium priority issue or pull request
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Association decorators should not show error notifications
2 participants