When using the Emberfire (Firebase) adapter, I'm getting various errors that indicate the tests are not waiting for data operations to complete.
eg: Error: Assertion Failed: You can only unload a record which is not inFlight. when I try to create, check, and then delete a record
Also:
FIREBASE WARNING: Exception was thrown by user callback. Error: Called stop() outside of a test context at Object.extend.stop (http://localhost:4200/assets/test-support.js:3000:10) at exports.default._emberTestingAdaptersAdapter.default.extend.asyncStart
These errors do not occur while manually navigating through my app, nor when using the standard ember data adapter.
What is causing these errors and how do I avoid them?
Edit: although the symptoms are a bit different (no error thrown), it sounds like this problem may have the same root cause as the errors I've been seeing.
tl;dr
To work around the issue, I've been using a custom test waiter. You can install it with ember install ember-cli-test-model-waiter (works with Ember v2.0+)
Longer answer:
The root cause of these problems is that the ember testing system doesn't know how to handle Firebase's asynchronicity. With most adapters, this isn't a problem, because the testing system instruments AJAX calls and ensures they have completed before proceeding, but this doesn't work with Firebase's websockets communication.
So although these errors don't occur when interacting manually, I believe they technically could if it were possible to click fast enough.
These problems are known to occur with ember-pouch and will likely also occur with other non-AJAX adapters (eg. localstorage adapters (1, 2), or any other websockets-based adapter. It may occur with the fixture adapter, but that may return results immediately and so not trigger this problem). It also happens with other asynchronous processes, like liquid-fire animations (fixed in a similar way)
The custom test waiter I mentioned in the tl;dr works by waiting for all models to resolve before proceeding with the test, and so should work with all of these non-AJAX adapters.
For more background on how ember's testing deals with asynchronicity under the hood, Cory Forsyth has a helpful blog post, and this gist gives another more flexible solution approach but that requires more manual book-keeping.
Related
Is there any kind of javascript error that is not handled by onerror in an ember(-cli) application? In other terms, is there any need to add a handler to window.onerror?
In my tests I could not come up with any error that would no be handled by Ember's onerror. Syntax errors didn't get past ember-cli's build process.
EmberJS does an excellent job of containing errors that happen within its boundaries. Errors caused by your Ember code should all get funneled into the Ember-specific handler.
However, browser JavaScript is a complicated beast. Any JavaScript errors that happen outside of Ember would not be captured internally and may only be exposed by the global window.onerror. Some examples of these could include:
Unbounded callbacks into native functions like setTimeout and addEventListener
Non-ember JavaScript libraries and integrations, such as Stripe, Twitter, or Advertisements
Browser-extension script that can interact with the DOM in unpredictable ways.
To get a complete picture of what is happening with your visitors, you should probably attach to both Ember.onerror and window.onerror and send the reports back to your logs. Even if you are not actively developing, browser changes can cause sudden bugs to appear in your application. Like this webkit bug that caused ember to throw errors. There are good options to record errors automatically from Ember apps, like TrackJS.
Disclosure: I am one of the founding developers of TrackJS, so I've debugged a lot of errors :)
In my experience, I would not advise implementing a window.onerror, unless you have a strong reason to do so and you know what you may be doing.
To my knowledge all of Ember's onerror methods piggy-back on to window.onerror and overriding it has potential to override/disable all the error in your app.
Case in point, I had an experience recently where i noticed that all my js errors stopped logging to console altogether. The reason was that another developer in my team had bootstrapped into my index.html to inject a <script> tag which utilized window.onerror for some error reporting script. The result was that overriding window litterally disabled all of ember's onerror becuase they work in a bubbling fashion.
I think if you do want to override window.onerror you need to ensure that it always returns false so that it does not prevent default error handling on the browser.
See: https://developer.mozilla.org/en-US/docs/Web/API/GlobalEventHandlers/onerror
I hope that helps clarify to some degree.
Ember has a built in error event you can use in your routes
actions: {
error(error, transition) {
if (error && error.status === 400) {
//handle error
}
}
}
More Info: https://guides.emberjs.com/v2.0.0/routing/loading-and-error-substates/
I have problems with acceptance tests (ember 0.10.0). The thing is, tests run successfully if I run them one by one (passing test ID in URL), but when I try to run them all at once, they fail cause of some async problems I think (such as trying to click on an element which has not been rendered yet). Has anybody faced that? Here's the gist with the example of one of my tests
P.S. I tried to upgrade versions of: qunit, ember-qunit, ember-cli-qunit, but the problem still exists (edited)
UPD 1
Here's the screenshot: https://pp.vk.me/c627830/v627830110/e718/tAwcDMJ0J4g.jpg
UPD 2
I simplified tests as much as I could and now, 50 percent they r passing. I mean, I run all tests and they are marked as done successfully, I run all tests again and they are failed. That blows my mind.
Common reasons for failing are:
Some resource that is used by more than one test isn't reset properly between tests. Typical shared resources are: databases, files, environment settings, locks. This is the most probable cause.
Some asynchronous work gets different timing and doesn't complete in a time, and you use a timer instead of more reliable ways to wait for completion.
I have a model (DS.Model) with a few computed properties and it has a custom adapter that extends DS.Adapter. Nothing asynchronous that I know of is going on here, but in my qUnit test I get the error pasted below. It is fixed if I wrap my assertion in an Ember.run() block. Does anyone know why?
Error: Assertion Failed: You have turned on testing mode, which disabled the run-loop's autorun. You will need to wrap any code with asynchronous side-effects in a run at new Error (native)
Inspect your ember application with the inspector browser plugin, and look in the promises tab.
You'll see there are a large number of promises there, even for an app with minimal code.
This isn't much of an answer, but looking at the promises tab should show that ember handles asyncrony without us necessarily knowing about it.
My application creates a lot of "configuration" models (ie- they only live in the app at runtime and they won't ever be persisted). I load these on demand so my app is constantly creating records and then throwing them away.
//create a record that will never be persisted
this.store.createRecord('foo', {name: 'wat'});
In the past I would just do a clear of the store but I realized this doesn't actually "remove" anything. I've decided to use the unloadAll instead
this.store.unloadAll('foo');
... but I run into this error as I have these "configuration" models
Error while loading route: Error: Attempted to handle event
unloadRecord on while in state
root.loaded.created.uncommitted.
at new Error (native)
How can I avoid this error (while still using the unloadAll as I need to truly remove these from the browser) ?
Actually this has now (should be) fixed with my PR which was merged 2 days ago:
see: https://github.com/emberjs/data/pull/1714
That PR loosens the constraint which disallowed unloading all dirty records, to disallowing only inFlight records. I believe with some time and proper thought, that constraint may also be lifted.
The rest of the PR, is specifically around proper cleanup when unloading a model, a record array, or destroying the store. I do believe this is a good first pass at proper cleanup.
I hope this (merged) PR solves your issue, if not please open a descriptive issue, and lets squash the bug.
I am developing an application using Django that works similar to a project manager. For this reason, the system should be capable of storing information about everything. When I say everything I refer to the actions the users do, the errors that occurred while doing an action, etc.
I have a class Log and one of its attributes is called action_type, this attribute specifies what kind of action just happened. I am supposed to have 5 kinds of types:
INFO: this log stores the information related to user's actions such as creating a project, create other users, etc.
DEBUG: should store comments made by the developers that will allow them to detect errors.
ERROR: shows errors that occurred in the system but they don't affect the system's functionality.
WARNING: it's for potentially damaging actions.
FATAL: unexpected errors, exceptions and security breaches.
I can only come up with logical logs for INFO.
Could you tell me some reasonable logs that I should include in this and the other categories?
The answer will depend greatly on exactly what your application does, but my basic approach is this:
Each time you get ready to log an event, just think about the event and it will be clear where it belongs. Did it kill your application? It's fatal. Did it prevent something from working correctly? It's an error. Could it prevent something from working, and did we just get lucky this time? It's a warning. Does anyone care? Info. Otherwise, if you still need to log it, it must be for debugging purposes.
In your particular context, it sounds like you might only be trying to log user actions. If that is the case, the only actions that could be fatal would be ones for which you don't provide an undo option (or, I suppose, if the user is able to order a piano bench and a length of strong rope through your application). I also couldn't really imagine any debug-level logs coming from user actions. Because of this, I assume you will be logging code level events in addition to user actions.
FATAL: This should only appear in the logs when your application actually crashes, and possibly alongside 500 responses. You might generate these within your wsgi application in a catch-all, only when the process would otherwise have died.
ERROR: Likely tied to http error responses. This is typically for errors caused by something outside your application. Things that happen in your code are probably expected and <= warning level, or unexpected and fatal. Errors might be a 404 from the user making a typo in a url, validation errors on form submission, or authentication errors. From the other direction, errors might be returned from remote web services that you contact or IO errors from the os.
WARNING: For things that don't break anything, but that might bite you if you keep it up. Examples are using deprecated apis and anywhere something only worked because of the default (time zone, character encoding, etc). Maybe certain input values result in warnings, too, like setting a due date in the past.
INFO: General, healthy operation. Someone created a database row (a new project or a task?), created an account, logged in or out, a socket was successfully opened, etc.
DEBUG: Just what it says. Output that you will usually turn off once the code is working correctly. Method entry/exit, object instantiation, field values at various points in the code, counters. Whatever you need to figure out why your program is crashing right now, as you work on it.