Skip to content

Host.delete() completes but never emits #14235

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

Closed
mina-skunk opened this issue Apr 22, 2019 · 1 comment · Fixed by #14242
Closed

Host.delete() completes but never emits #14235

mina-skunk opened this issue Apr 22, 2019 · 1 comment · Fixed by #14242
Assignees
Labels
area: @angular-devkit/core freq1: low Only reported by a handful of users who observe it rarely severity3: broken type: bug/fix
Milestone

Comments

@mina-skunk
Copy link

mina-skunk commented Apr 22, 2019

🐞 Bug report

Command (mark with an x)

- [ ] new
- [x] build
- [ ] serve
- [ ] test
- [ ] e2e
- [ ] generate
- [ ] add
- [ ] update
- [ ] lint
- [ ] xi18n
- [x] run
- [ ] config
- [ ] help
- [ ] version
- [ ] doc

Description

The observable returned by Host.delete() completes but never emits.

🔬 Minimal Reproduction

With the following builder and path being a dir that exists

export interface MyBuilderOptions {
  path: string;
}

export class MyBuilder implements Builder<MyBuilderOptions> {

  constructor(
    private context: BuilderContext
  ) { }

  public run({ options }: BuilderConfiguration<MyBuilderOptions>): Observable<BuildEvent> {
    return this.deleteIfExist(options.path).pipe(
      map(() => {
        return { success: true } as BuildEvent;
      })
    );
  }

  private deleteIfExist(path: string): Observable<void> {
    const fullPath = resolve(this.context.workspace.root, normalize(path));
    return this.context.host.exists(fullPath).pipe(
      tap(
        res => console.log(`exists:emit:${res}`), // true
        err => console.log(`exists:error:${err}`), // not hit
        () => console.log(`exists:complete`) // hit
      ),
      switchMap(exists => {
        console.log(`if (exists) => ${exists}`); // true
        if (exists) {
          return this.context.host.delete(fullPath).pipe(
            tap(
              res => console.log(`delete:emit:${res}`), // not hit
              err => console.log(`delete:error:${err}`), // not hit
              () => console.log(`delete:complete`) // hit
            )
          );
        }
        return of(null);
      }),
      tap(
        res => console.log(`return:emit:${res}`), // not hit
        err => console.log(`return:error:${err}`), // not hit
        () => console.log(`return:complete`) // hit
      )
    );
  }

}

the output is:

exists:emit:true
if (exists) => true
delete:complete
exists:complete
return:complete
Cannot read property 'success' of undefined
at RunCommand.runSingleTarget

notice that delete:emit and return:emit never hit

but if the dir dosn't exist

export class MyBuilder implements Builder<MyBuilderOptions> {
//...
  private deleteIfExist(path: string): Observable<void> {
    const fullPath = resolve(this.context.workspace.root, normalize(path));
    return this.context.host.exists(fullPath).pipe(
      tap(
        res => console.log(`exists:emit:${res}`), // false
        err => console.log(`exists:error:${err}`), // not hit
        () => console.log(`exists:complete`) // hit
      ),
      switchMap(exists => {
        console.log(`if (exists) => ${exists}`); // false
        if (exists) {
          return this.context.host.delete(fullPath).pipe(
            tap(
              res => console.log(`delete:emit:${res}`), // not hit
              err => console.log(`delete:error:${err}`), // not hit
              () => console.log(`delete:complete`) // not hit
            )
          );
        }
        return of(null);
      }),
      tap(
        res => console.log(`return:emit:${res}`), // null
        err => console.log(`return:error:${err}`), // not hit
        () => console.log(`return:complete`) // hit
      )
    );
  }
//...
}

the output is:

exists:emit:false
if (exists) => false
return:emit:null
exists:complete
return:complete

(with no error) notice that return:emit does hit

If the code path reaches Host.delete() the observable stream "short circuits" and completes immediately, causing the map(() => { return { success: true }; }) to never happen. Shouldn't it emit void then complete if successful.

🔥 Exception or Error

Cannot read property 'success' of undefined
TypeError: Cannot read property 'success' of undefined
at RunCommand.runSingleTarget (C:\Users\User\source\repos\autofluent-cloud\autofluent-clients\cli6\node_modules@angular\cli\models\architect-command.js:184:27)
at process._tickCallback (internal/process/next_tick.js:68:7)
at Function.Module.runMain (internal/modules/cjs/loader.js:744:11)
at startup (internal/bootstrap/node.js:285:19)
at bootstrapNodeJSCore (internal/bootstrap/node.js:739:3)

🌍 Your Environment


Angular CLI: 7.3.8
Node: 10.14.1
OS: win32 x64
Angular: 7.2.7
... animations, common, compiler, compiler-cli, core, forms
... http, language-service, platform-browser
... platform-browser-dynamic, router

Package                            Version
------------------------------------------------------------
@angular-devkit/architect          0.13.8
@angular-devkit/build-angular      0.13.8
@angular-devkit/build-ng-packagr   0.13.8
@angular-devkit/build-optimizer    0.13.8
@angular-devkit/build-webpack      0.13.8
@angular-devkit/core               7.3.8
@angular-devkit/schematics         7.3.8
@angular/cdk                       7.3.3
@angular/cli                       7.3.8
@angular/flex-layout               7.0.0-beta.23
@angular/material                  7.3.3
@ngtools/json-schema               1.1.0
@ngtools/webpack                   7.3.8
@schematics/angular                7.3.8
@schematics/update                 0.13.8
ng-packagr                         4.7.1
rxjs                               6.3.3
typescript                         3.2.4
webpack                            4.29.0

Anything else relevant?
The only workaround I found to work was

from(this.context.host.delete(fullPath).toPromise())
@alan-agius4 alan-agius4 added area: @angular-devkit/core freq1: low Only reported by a handful of users who observe it rarely severity3: broken labels Apr 23, 2019
@ngbot ngbot bot added this to the needsTriage milestone Apr 23, 2019
@ngbot ngbot bot modified the milestones: needsTriage, Backlog Apr 23, 2019
@alan-agius4 alan-agius4 self-assigned this Apr 23, 2019
alexeagle pushed a commit that referenced this issue Apr 23, 2019
RxJS `EMPTY` creates an Observable that emits no items immediately emits a complete notification.

Fixes #14235
@angular-automatic-lock-bot
Copy link

This issue has been automatically locked due to inactivity.
Please file a new issue if you are encountering a similar or related problem.

Read more about our automatic conversation locking policy.

This action has been performed automatically by a bot.

@angular-automatic-lock-bot angular-automatic-lock-bot bot locked and limited conversation to collaborators Sep 9, 2019
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
area: @angular-devkit/core freq1: low Only reported by a handful of users who observe it rarely severity3: broken type: bug/fix
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants